diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-11-07 21:14:21 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-11-07 21:46:06 +0100 |
commit | 2060895c9ce71bba5a950827167f23ae9eb6eef5 (patch) | |
tree | 70fb7311b7406554ab29bc12b99e68911eb07349 /llvm/unittests/IR/ConstantRangeTest.cpp | |
parent | cf71a5ea8f95be423ebd381d21d0f9a05edc5018 (diff) | |
download | llvm-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.cpp | 17 |
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); }); |