Fix demanded bits analysis with srem by negative number. Based on a patch
authorNick Lewycky <nicholas@mxc.ca>
Sun, 2 Nov 2008 02:41:50 +0000 (02:41 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sun, 2 Nov 2008 02:41:50 +0000 (02:41 +0000)
by Richard Osborne.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58555 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2008-11-01-SRemDemandedBits.ll [new file with mode: 0644]

index 75a1ffea6b5964ceea80e484560328443bc86f5e..3210b12cbb96ac86afa9d8a15e5ee11db863a96b 100644 (file)
@@ -1274,12 +1274,12 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask,
     break;
   case Instruction::SRem:
     if (ConstantInt *Rem = dyn_cast<ConstantInt>(I->getOperand(1))) {
-      APInt RA = Rem->getValue();
-      if (RA.isPowerOf2() || (-RA).isPowerOf2()) {
+      APInt RA = Rem->getValue().abs();
+      if (RA.isPowerOf2()) {
         if (DemandedMask.ule(RA))    // srem won't affect demanded bits
           return UpdateValueUsesWith(I, I->getOperand(0));
 
-        APInt LowBits = RA.isStrictlyPositive() ? (RA - 1) : ~RA;
+        APInt LowBits = RA - 1;
         APInt Mask2 = LowBits | APInt::getSignBit(BitWidth);
         if (SimplifyDemandedBits(I->getOperand(0), Mask2,
                                  LHSKnownZero, LHSKnownOne, Depth+1))
diff --git a/test/Transforms/InstCombine/2008-11-01-SRemDemandedBits.ll b/test/Transforms/InstCombine/2008-11-01-SRemDemandedBits.ll
new file mode 100644 (file)
index 0000000..46e98eb
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i1 true}
+; PR2993
+
+define i1 @foo(i32 %x) {
+  %1 = srem i32 %x, -1
+  %2 = icmp eq i32 %1, 0
+  ret i1 %2
+}