summaryrefslogtreecommitdiffstats
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.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp
index eeebe2e73ae..c0166b21039 100644
--- a/llvm/unittests/IR/ConstantRangeTest.cpp
+++ b/llvm/unittests/IR/ConstantRangeTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/BitVector.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
@@ -844,6 +845,63 @@ TEST_F(ConstantRangeTest, UDiv) {
ConstantRange(APInt(16, 0), APInt(16, 99)));
}
+TEST_F(ConstantRangeTest, SDiv) {
+ unsigned Bits = 4;
+ EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
+ const ConstantRange &CR2) {
+ // Collect possible results in a bit vector. We store the signed value plus
+ // a bias to make it unsigned.
+ int Bias = 1 << (Bits - 1);
+ BitVector Results(1 << Bits);
+ ForeachNumInConstantRange(CR1, [&](const APInt &N1) {
+ ForeachNumInConstantRange(CR2, [&](const APInt &N2) {
+ // Division by zero is UB.
+ if (N2 == 0)
+ return;
+
+ // SignedMin / -1 is UB.
+ if (N1.isMinSignedValue() && N2.isAllOnesValue())
+ return;
+
+ APInt N = N1.sdiv(N2);
+ Results.set(N.getSExtValue() + Bias);
+ });
+ });
+
+ ConstantRange CR = CR1.sdiv(CR2);
+ if (Results.none()) {
+ EXPECT_TRUE(CR.isEmptySet());
+ return;
+ }
+
+ // If there is a non-full signed envelope, that should be the result.
+ APInt SMin(Bits, Results.find_first() - Bias);
+ APInt SMax(Bits, Results.find_last() - Bias);
+ ConstantRange Envelope = ConstantRange::getNonEmpty(SMin, SMax + 1);
+ if (!Envelope.isFullSet()) {
+ EXPECT_EQ(Envelope, CR);
+ return;
+ }
+
+ // If the signed envelope is a full set, try to find a smaller sign wrapped
+ // set that is separated in negative and positive components (or one which
+ // can also additionally contain zero).
+ int LastNeg = Results.find_last_in(0, Bias) - Bias;
+ int LastPos = Results.find_next(Bias) - Bias;
+ if (Results[Bias]) {
+ if (LastNeg == -1)
+ ++LastNeg;
+ else if (LastPos == 1)
+ --LastPos;
+ }
+
+ APInt WMax(Bits, LastNeg);
+ APInt WMin(Bits, LastPos);
+ ConstantRange Wrapped = ConstantRange::getNonEmpty(WMin, WMax + 1);
+ EXPECT_EQ(Wrapped, CR);
+ });
+}
+
TEST_F(ConstantRangeTest, URem) {
EXPECT_EQ(Full.urem(Empty), Empty);
EXPECT_EQ(Empty.urem(Full), Empty);
OpenPOWER on IntegriCloud