From 2060895c9ce71bba5a950827167f23ae9eb6eef5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 7 Nov 2021 21:14:21 +0100 Subject: [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 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. --- llvm/unittests/IR/ConstantRangeTest.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp') 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 -void testBinarySetOperationExhaustive(Fn1 OpFn, Fn2 InResultFn) { +template +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 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); }); -- cgit v1.1