Add more analysis of the sign bit of an srem instruction. If the LHS is negative
authorNick Lewycky <nicholas@mxc.ca>
Mon, 7 Mar 2011 01:50:10 +0000 (01:50 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Mon, 7 Mar 2011 01:50:10 +0000 (01:50 +0000)
then the result could go either way. If it's provably positive then so is the
srem. Fixes PR9343 #7!

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

lib/Analysis/ValueTracking.cpp
lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
test/Transforms/InstCombine/icmp.ll

index 82f4f64fc65711b46f1ede7c6357275bf43f60cc..231b95b618fdbe6c1bec3de9dd7d7264d0bfcd2a 100644 (file)
@@ -460,6 +460,19 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
         assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); 
       }
     }
+
+    // The sign bit is the LHS's sign bit, except when the result of the
+    // remainder is zero.
+    if (Mask.isNegative() && KnownZero.isNonNegative()) {
+      APInt Mask2 = APInt::getSignBit(BitWidth);
+      APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
+      ComputeMaskedBits(I->getOperand(0), Mask2, LHSKnownZero, LHSKnownOne, TD,
+                        Depth+1);
+      // If it's known zero, our sign bit is also zero.
+      if (LHSKnownZero.isNegative())
+        KnownZero |= LHSKnownZero;
+    }
+
     break;
   case Instruction::URem: {
     if (ConstantInt *Rem = dyn_cast<ConstantInt>(I->getOperand(1))) {
index bda8cea4e41f1d6889be6232628db867c050f734..b12d4c368740237e0647dc48848b20fd44ba5d81 100644 (file)
@@ -712,6 +712,18 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
         assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?"); 
       }
     }
+
+    // The sign bit is the LHS's sign bit, except when the result of the
+    // remainder is zero.
+    if (DemandedMask.isNegative() && KnownZero.isNonNegative()) {
+      APInt Mask2 = APInt::getSignBit(BitWidth);
+      APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
+      ComputeMaskedBits(I->getOperand(0), Mask2, LHSKnownZero, LHSKnownOne,
+                        Depth+1);
+      // If it's known zero, our sign bit is also zero.
+      if (LHSKnownZero.isNegative())
+        KnownZero |= LHSKnownZero;
+    }
     break;
   case Instruction::URem: {
     APInt KnownZero2(BitWidth, 0), KnownOne2(BitWidth, 0);
index 63f76313f8ec5e9508d54d1ff9bacd28bcae1845..bf0107adf06e7d657c66f8f6d5cc084dc200f968 100644 (file)
@@ -475,3 +475,22 @@ entry:
   %cmp = icmp ult <2 x i32> %tmp11, <i32 4, i32 4>
   ret <2 x i1> %cmp  
 }
+
+; PR9343 #7
+; CHECK: @test50
+; CHECK: ret i1 true
+define i1 @test50(i16 %X, i32 %Y) {
+  %A = zext i16 %X to i32
+  %B = srem i32 %A, %Y
+  %C = icmp sgt i32 %B, -1
+  ret i1 %C
+}
+
+; CHECK: @test51
+; CHECK: ret i1 %C
+define i1 @test51(i16 %X, i32 %Y) {
+  %A = sext i16 %X to i32
+  %B = srem i32 %A, %Y
+  %C = icmp sgt i32 %B, -1
+  ret i1 %C
+}