aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/IR/ConstantRangeTest.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-11-07 21:14:21 +0100
committerNikita Popov <nikita.ppv@gmail.com>2021-11-07 21:46:06 +0100
commit2060895c9ce71bba5a950827167f23ae9eb6eef5 (patch)
tree70fb7311b7406554ab29bc12b99e68911eb07349 /llvm/unittests/IR/ConstantRangeTest.cpp
parentcf71a5ea8f95be423ebd381d21d0f9a05edc5018 (diff)
downloadllvm-2060895c9ce71bba5a950827167f23ae9eb6eef5.zip
llvm-2060895c9ce71bba5a950827167f23ae9eb6eef5.tar.gz
llvm-2060895c9ce71bba5a950827167f23ae9eb6eef5.tar.bz2
[ConstantRange] Add exact union/intersect (NFC)
For some optimizations on comparisons it's necessary that the union/intersect is exact and not a superset. Add methods that return Optional<ConstantRange> only if the result is exact. For the sake of simplicity this is implemented by comparing the subset and superset approximations for now, but it should be possible to do this more directly, as unionWith() and intersectWith() already distinguish the cases where the result is imprecise for the preferred range type functionality.
Diffstat (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r--llvm/unittests/IR/ConstantRangeTest.cpp17
1 files changed, 15 insertions, 2 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp
index 2de1ae7..17cc29b 100644
--- a/llvm/unittests/IR/ConstantRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantRangeTest.cpp
@@ -558,8 +558,8 @@ TEST_F(ConstantRangeTest, IntersectWith) {
EXPECT_EQ(LHS.intersectWith(RHS), ConstantRange(APInt(32, 15), APInt(32, 0)));
}
-template<typename Fn1, typename Fn2>
-void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 InResultFn) {
+template<typename Fn1, typename Fn2, typename Fn3>
+void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 ExactOpFn, Fn3 InResultFn) {
unsigned Bits = 4;
EnumerateTwoConstantRanges(Bits,
[=](const ConstantRange &CR1, const ConstantRange &CR2) {
@@ -577,6 +577,13 @@ void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 InResultFn) {
ConstantRange SignedCR = OpFn(CR1, CR2, ConstantRange::Signed);
TestRange(SignedCR, Elems, PreferSmallestNonFullSigned, {CR1, CR2});
+
+ Optional<ConstantRange> ExactCR = ExactOpFn(CR1, CR2);
+ if (SmallestCR.isSizeLargerThan(Elems.count())) {
+ EXPECT_TRUE(!ExactCR.hasValue());
+ } else {
+ EXPECT_EQ(SmallestCR, *ExactCR);
+ }
});
}
@@ -586,6 +593,9 @@ TEST_F(ConstantRangeTest, IntersectWithExhaustive) {
ConstantRange::PreferredRangeType Type) {
return CR1.intersectWith(CR2, Type);
},
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.exactIntersectWith(CR2);
+ },
[](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {
return CR1.contains(N) && CR2.contains(N);
});
@@ -597,6 +607,9 @@ TEST_F(ConstantRangeTest, UnionWithExhaustive) {
ConstantRange::PreferredRangeType Type) {
return CR1.unionWith(CR2, Type);
},
+ [](const ConstantRange &CR1, const ConstantRange &CR2) {
+ return CR1.exactUnionWith(CR2);
+ },
[](const ConstantRange &CR1, const ConstantRange &CR2, const APInt &N) {
return CR1.contains(N) || CR2.contains(N);
});