[ConstantRange] Fix sdiv() with one bit values (PR56333)
authorNikita Popov <npopov@redhat.com>
Fri, 1 Jul 2022 13:43:27 +0000 (15:43 +0200)
committerNikita Popov <npopov@redhat.com>
Fri, 1 Jul 2022 13:44:59 +0000 (15:44 +0200)
Signed one bit values can only be -1 or 0, not positive. The code
was interpreting the 1 as -1 and intersecting with a full range
rather than an empty one.

Fixes https://github.com/llvm/llvm-project/issues/56333.

llvm/lib/IR/ConstantRange.cpp
llvm/unittests/IR/ConstantRangeTest.cpp

index be6386c..9d23910 100644 (file)
@@ -1238,7 +1238,10 @@ ConstantRange ConstantRange::sdiv(const ConstantRange &RHS) const {
   // separately by combining division results with the appropriate signs.
   APInt Zero = APInt::getZero(getBitWidth());
   APInt SignedMin = APInt::getSignedMinValue(getBitWidth());
-  ConstantRange PosFilter(APInt(getBitWidth(), 1), SignedMin);
+  // There are no positive 1-bit values. The 1 would get interpreted as -1.
+  ConstantRange PosFilter =
+      getBitWidth() == 1 ? getEmpty()
+                         : ConstantRange(APInt(getBitWidth(), 1), SignedMin);
   ConstantRange NegFilter(SignedMin, Zero);
   ConstantRange PosL = intersectWith(PosFilter);
   ConstantRange NegL = intersectWith(NegFilter);
index ced38a2..edea097 100644 (file)
@@ -1259,6 +1259,9 @@ TEST_F(ConstantRangeTest, UDiv) {
 }
 
 TEST_F(ConstantRangeTest, SDiv) {
+  ConstantRange OneBit = ConstantRange::getFull(1);
+  EXPECT_EQ(OneBit.sdiv(OneBit), ConstantRange(APInt(1, 0)));
+
   unsigned Bits = 4;
   EnumerateTwoConstantRanges(Bits, [&](const ConstantRange &CR1,
                                        const ConstantRange &CR2) {