aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/IR/ConstantRangeTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r--llvm/unittests/IR/ConstantRangeTest.cpp277
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));
}