diff options
Diffstat (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r-- | llvm/unittests/IR/ConstantRangeTest.cpp | 277 |
1 files changed, 137 insertions, 140 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index 19474ee..5e8a98e 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -59,107 +59,130 @@ static void ForeachNumInConstantRange(const ConstantRange &CR, Fn TestFn) { } } -template<typename Fn1, typename Fn2> -static void TestUnsignedUnaryOpExhaustive( - Fn1 RangeFn, Fn2 IntFn, bool SkipSignedIntMin = false) { +struct OpRangeGathererBase { + void account(const APInt &N); + ConstantRange getRange(); +}; + +struct UnsignedOpRangeGatherer : public OpRangeGathererBase { + APInt Min; + APInt Max; + + UnsignedOpRangeGatherer(unsigned Bits) + : Min(APInt::getMaxValue(Bits)), Max(APInt::getMinValue(Bits)) {} + + void account(const APInt &N) { + if (N.ult(Min)) + Min = N; + if (N.ugt(Max)) + Max = N; + } + + ConstantRange getRange() { + if (Min.ugt(Max)) + return ConstantRange::getEmpty(Min.getBitWidth()); + return ConstantRange::getNonEmpty(Min, Max + 1); + } +}; + +struct SignedOpRangeGatherer : public OpRangeGathererBase { + APInt Min; + APInt Max; + + SignedOpRangeGatherer(unsigned Bits) + : Min(APInt::getSignedMaxValue(Bits)), + Max(APInt::getSignedMinValue(Bits)) {} + + void account(const APInt &N) { + if (N.slt(Min)) + Min = N; + if (N.sgt(Max)) + Max = N; + } + + ConstantRange getRange() { + if (Min.sgt(Max)) + return ConstantRange::getEmpty(Min.getBitWidth()); + return ConstantRange::getNonEmpty(Min, Max + 1); + } +}; + +template <typename Fn1, typename Fn2> +static void TestUnsignedUnaryOpExhaustive(Fn1 RangeFn, Fn2 IntFn, + bool SkipSignedIntMin = false) { unsigned Bits = 4; EnumerateConstantRanges(Bits, [&](const ConstantRange &CR) { - APInt Min = APInt::getMaxValue(Bits); - APInt Max = APInt::getMinValue(Bits); + UnsignedOpRangeGatherer R(CR.getBitWidth()); ForeachNumInConstantRange(CR, [&](const APInt &N) { if (SkipSignedIntMin && N.isMinSignedValue()) return; - - APInt AbsN = IntFn(N); - if (AbsN.ult(Min)) - Min = AbsN; - if (AbsN.ugt(Max)) - Max = AbsN; + R.account(IntFn(N)); }); - ConstantRange ResultCR = RangeFn(CR); - if (Min.ugt(Max)) { - EXPECT_TRUE(ResultCR.isEmptySet()); - return; - } + ConstantRange ExactCR = R.getRange(); + ConstantRange ActualCR = RangeFn(CR); - ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1); - EXPECT_EQ(Exact, ResultCR); + EXPECT_EQ(ExactCR, ActualCR); }); } -template<typename Fn1, typename Fn2> -static void TestUnsignedBinOpExhaustive( - Fn1 RangeFn, Fn2 IntFn, - bool SkipZeroRHS = false, bool CorrectnessOnly = false) { +template <typename Fn1, typename Fn2> +static void TestUnsignedBinOpExhaustive(Fn1 RangeFn, Fn2 IntFn, + bool SkipZeroRHS = false, + bool CorrectnessOnly = false) { unsigned Bits = 4; - EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1, - const ConstantRange &CR2) { - APInt Min = APInt::getMaxValue(Bits); - APInt Max = APInt::getMinValue(Bits); - ForeachNumInConstantRange(CR1, [&](const APInt &N1) { - ForeachNumInConstantRange(CR2, [&](const APInt &N2) { - if (SkipZeroRHS && N2 == 0) - return; + EnumerateTwoConstantRanges( + Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) { + UnsignedOpRangeGatherer R(CR1.getBitWidth()); + ForeachNumInConstantRange(CR1, [&](const APInt &N1) { + ForeachNumInConstantRange(CR2, [&](const APInt &N2) { + if (SkipZeroRHS && N2 == 0) + return; + R.account(IntFn(N1, N2)); + }); + }); - APInt N = IntFn(N1, N2); - if (N.ult(Min)) - Min = N; - if (N.ugt(Max)) - Max = N; - }); - }); + ConstantRange CR = RangeFn(CR1, CR2); - ConstantRange CR = RangeFn(CR1, CR2); - if (Min.ugt(Max)) { - EXPECT_TRUE(CR.isEmptySet()); - return; - } + ConstantRange Exact = R.getRange(); - ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1); - if (CorrectnessOnly) { - EXPECT_TRUE(CR.contains(Exact)); - } else { - EXPECT_EQ(Exact, CR); - } - }); + if (!CorrectnessOnly) { + EXPECT_EQ(Exact, CR); + return; + } + + EXPECT_TRUE(CR.contains(Exact)); + if (Exact.isEmptySet()) + EXPECT_TRUE(CR.isEmptySet()); + }); } -template<typename Fn1, typename Fn2> -static void TestSignedBinOpExhaustive( - Fn1 RangeFn, Fn2 IntFn, - bool SkipZeroRHS = false, bool CorrectnessOnly = false) { +template <typename Fn1, typename Fn2> +static void TestSignedBinOpExhaustive(Fn1 RangeFn, Fn2 IntFn, + bool SkipZeroRHS = false, + bool CorrectnessOnly = false) { unsigned Bits = 4; - EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1, - const ConstantRange &CR2) { - APInt Min = APInt::getSignedMaxValue(Bits); - APInt Max = APInt::getSignedMinValue(Bits); - ForeachNumInConstantRange(CR1, [&](const APInt &N1) { - ForeachNumInConstantRange(CR2, [&](const APInt &N2) { - if (SkipZeroRHS && N2 == 0) - return; + EnumerateTwoConstantRanges( + Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) { + SignedOpRangeGatherer R(CR1.getBitWidth()); + ForeachNumInConstantRange(CR1, [&](const APInt &N1) { + ForeachNumInConstantRange(CR2, [&](const APInt &N2) { + if (SkipZeroRHS && N2 == 0) + return; - APInt N = IntFn(N1, N2); - if (N.slt(Min)) - Min = N; - if (N.sgt(Max)) - Max = N; - }); - }); + R.account(IntFn(N1, N2)); + }); + }); - ConstantRange CR = RangeFn(CR1, CR2); - if (Min.sgt(Max)) { - EXPECT_TRUE(CR.isEmptySet()); - return; - } + ConstantRange CR = RangeFn(CR1, CR2); - ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1); - if (CorrectnessOnly) { - EXPECT_TRUE(CR.contains(Exact)); - } else { - EXPECT_EQ(Exact, CR); - } - }); + ConstantRange Exact = R.getRange(); + if (CorrectnessOnly) { + EXPECT_TRUE(CR.contains(Exact)); + } else { + EXPECT_EQ(Exact, CR); + } + }); } ConstantRange ConstantRangeTest::Full(16, true); @@ -731,8 +754,7 @@ static void TestAddWithNoSignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) { EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) { ConstantRange CR = RangeFn(CR1, CR2); - APInt Min = APInt::getSignedMaxValue(Bits); - APInt Max = APInt::getSignedMinValue(Bits); + SignedOpRangeGatherer R(CR.getBitWidth()); bool AllOverflow = true; ForeachNumInConstantRange(CR1, [&](const APInt &N1) { ForeachNumInConstantRange(CR2, [&](const APInt &N2) { @@ -740,10 +762,7 @@ static void TestAddWithNoSignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) { APInt N = IntFn(IsOverflow, N1, N2); if (!IsOverflow) { AllOverflow = false; - if (N.slt(Min)) - Min = N; - if (N.sgt(Max)) - Max = N; + R.account(N); EXPECT_TRUE(CR.contains(N)); } }); @@ -751,15 +770,11 @@ static void TestAddWithNoSignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) { EXPECT_EQ(CR.isEmptySet(), AllOverflow); - if (!CR1.isSignWrappedSet() && !CR2.isSignWrappedSet()) { - if (Min.sgt(Max)) { - EXPECT_TRUE(CR.isEmptySet()); - return; - } + if (CR1.isSignWrappedSet() || CR2.isSignWrappedSet()) + return; - ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1); - EXPECT_EQ(Exact, CR); - } + ConstantRange Exact = R.getRange(); + EXPECT_EQ(Exact, CR); }); } @@ -769,8 +784,7 @@ static void TestAddWithNoUnsignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) { EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) { ConstantRange CR = RangeFn(CR1, CR2); - APInt Min = APInt::getMaxValue(Bits); - APInt Max = APInt::getMinValue(Bits); + UnsignedOpRangeGatherer R(CR.getBitWidth()); bool AllOverflow = true; ForeachNumInConstantRange(CR1, [&](const APInt &N1) { ForeachNumInConstantRange(CR2, [&](const APInt &N2) { @@ -778,10 +792,7 @@ static void TestAddWithNoUnsignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) { APInt N = IntFn(IsOverflow, N1, N2); if (!IsOverflow) { AllOverflow = false; - if (N.ult(Min)) - Min = N; - if (N.ugt(Max)) - Max = N; + R.account(N); EXPECT_TRUE(CR.contains(N)); } }); @@ -789,15 +800,11 @@ static void TestAddWithNoUnsignedWrapExhaustive(Fn1 RangeFn, Fn2 IntFn) { EXPECT_EQ(CR.isEmptySet(), AllOverflow); - if (!CR1.isWrappedSet() && !CR2.isWrappedSet()) { - if (Min.ugt(Max)) { - EXPECT_TRUE(CR.isEmptySet()); - return; - } + if (CR1.isWrappedSet() || CR2.isWrappedSet()) + return; - ConstantRange Exact = ConstantRange::getNonEmpty(Min, Max + 1); - EXPECT_EQ(Exact, CR); - } + ConstantRange Exact = R.getRange(); + EXPECT_EQ(Exact, CR); }); } @@ -809,10 +816,8 @@ static void TestAddWithNoSignedUnsignedWrapExhaustive(Fn1 RangeFn, EnumerateTwoConstantRanges( Bits, [&](const ConstantRange &CR1, const ConstantRange &CR2) { ConstantRange CR = RangeFn(CR1, CR2); - APInt UMin = APInt::getMaxValue(Bits); - APInt UMax = APInt::getMinValue(Bits); - APInt SMin = APInt::getSignedMaxValue(Bits); - APInt SMax = APInt::getSignedMinValue(Bits); + UnsignedOpRangeGatherer UR(CR.getBitWidth()); + SignedOpRangeGatherer SR(CR.getBitWidth()); bool AllOverflow = true; ForeachNumInConstantRange(CR1, [&](const APInt &N1) { ForeachNumInConstantRange(CR2, [&](const APInt &N2) { @@ -821,14 +826,8 @@ static void TestAddWithNoSignedUnsignedWrapExhaustive(Fn1 RangeFn, (void) IntFnUnsigned(IsOverflow, N1, N2); if (!IsSignedOverflow && !IsOverflow) { AllOverflow = false; - if (N.slt(SMin)) - SMin = N; - if (N.sgt(SMax)) - SMax = N; - if (N.ult(UMin)) - UMin = N; - if (N.ugt(UMax)) - UMax = N; + UR.account(N); + SR.account(N); EXPECT_TRUE(CR.contains(N)); } }); @@ -836,18 +835,20 @@ static void TestAddWithNoSignedUnsignedWrapExhaustive(Fn1 RangeFn, EXPECT_EQ(CR.isEmptySet(), AllOverflow); - if (!CR1.isWrappedSet() && !CR2.isWrappedSet() && - !CR1.isSignWrappedSet() && !CR2.isSignWrappedSet()) { - if (UMin.ugt(UMax) || SMin.sgt(SMax)) { - EXPECT_TRUE(CR.isEmptySet()); - return; - } + if (CR1.isWrappedSet() || CR2.isWrappedSet() || + CR1.isSignWrappedSet() || CR2.isSignWrappedSet()) + return; - ConstantRange Exact = - ConstantRange::getNonEmpty(SMin, SMax + 1) - .intersectWith(ConstantRange::getNonEmpty(UMin, UMax + 1)); - EXPECT_EQ(Exact, CR); + ConstantRange ExactUnsignedCR = UR.getRange(); + ConstantRange ExactSignedCR = SR.getRange(); + + if (ExactUnsignedCR.isEmptySet() || ExactSignedCR.isEmptySet()) { + EXPECT_TRUE(CR.isEmptySet()); + return; } + + ConstantRange Exact = ExactSignedCR.intersectWith(ExactUnsignedCR); + EXPECT_EQ(Exact, CR); }); } @@ -2229,23 +2230,19 @@ TEST_F(ConstantRangeTest, FromKnownBitsExhaustive) { if (Known.hasConflict() || Known.isUnknown()) continue; - APInt MinUnsigned = APInt::getMaxValue(Bits); - APInt MaxUnsigned = APInt::getMinValue(Bits); - APInt MinSigned = APInt::getSignedMaxValue(Bits); - APInt MaxSigned = APInt::getSignedMinValue(Bits); + UnsignedOpRangeGatherer UR(Bits); + SignedOpRangeGatherer SR(Bits); for (unsigned N = 0; N < Max; ++N) { APInt Num(Bits, N); if ((Num & Known.Zero) != 0 || (~Num & Known.One) != 0) continue; - if (Num.ult(MinUnsigned)) MinUnsigned = Num; - if (Num.ugt(MaxUnsigned)) MaxUnsigned = Num; - if (Num.slt(MinSigned)) MinSigned = Num; - if (Num.sgt(MaxSigned)) MaxSigned = Num; + UR.account(Num); + SR.account(Num); } - ConstantRange UnsignedCR(MinUnsigned, MaxUnsigned + 1); - ConstantRange SignedCR(MinSigned, MaxSigned + 1); + ConstantRange UnsignedCR = UR.getRange(); + ConstantRange SignedCR = SR.getRange(); EXPECT_EQ(UnsignedCR, ConstantRange::fromKnownBits(Known, false)); EXPECT_EQ(SignedCR, ConstantRange::fromKnownBits(Known, true)); } |