Teach ComputeMaskedBits about sub nsw.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sat, 12 Mar 2011 17:18:11 +0000 (17:18 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sat, 12 Mar 2011 17:18:11 +0000 (17:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127548 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ValueTracking.cpp
test/Transforms/InstSimplify/compare.ll

index 6c33d2d508e3167f29cfc61df6abbaca2798eb58..c36f68c2aeb99665074b3a446d3ba558005d86d9 100644 (file)
@@ -431,16 +431,24 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask,
     }
 
     // Are we still trying to solve for the sign bit?
-    if (I->getOpcode() == Instruction::Add &&
-        Mask.isNegative() && !KnownZero.isNegative() && !KnownOne.isNegative()){
+    if (Mask.isNegative() && !KnownZero.isNegative() && !KnownOne.isNegative()){
       OverflowingBinaryOperator *OBO = cast<OverflowingBinaryOperator>(I);
       if (OBO->hasNoSignedWrap()) {
-        // Adding two positive numbers can't wrap into negative ...
-        if (LHSKnownZero.isNegative() && KnownZero2.isNegative())
-          KnownZero |= APInt::getSignBit(BitWidth);
-        // and adding two negative numbers can't wrap into positive.
-        else if (LHSKnownOne.isNegative() && KnownOne2.isNegative())
-          KnownOne |= APInt::getSignBit(BitWidth);
+        if (I->getOpcode() == Instruction::Add) {
+          // Adding two positive numbers can't wrap into negative
+          if (LHSKnownZero.isNegative() && KnownZero2.isNegative())
+            KnownZero |= APInt::getSignBit(BitWidth);
+          // and adding two negative numbers can't wrap into positive.
+          else if (LHSKnownOne.isNegative() && KnownOne2.isNegative())
+            KnownOne |= APInt::getSignBit(BitWidth);
+        } else {
+          // Subtracting a negative number from a positive one can't wrap
+          if (LHSKnownZero.isNegative() && KnownOne2.isNegative())
+            KnownZero |= APInt::getSignBit(BitWidth);
+          // neither can subtracting a positive number from a negative one.
+          else if (LHSKnownOne.isNegative() && KnownZero2.isNegative())
+            KnownOne |= APInt::getSignBit(BitWidth);
+        }
       }
     }
 
index 75a36b499e37f53ac65e6850de62a88f35c72ce5..d2c564f567b44ed268f63f7f24c0ca6d335ca680 100644 (file)
@@ -271,6 +271,29 @@ define i1 @srem2(i16 %X, i32 %Y) {
   %D = icmp slt i32 %C, 0
   ret i1 %D
 }
+
+; CHECK: @srem3
+; CHECK-NEXT: ret i1 false
+define i1 @srem3(i16 %X, i32 %Y) {
+  %A = zext i16 %X to i32
+  %B = or i32 2147483648, %A
+  %C = sub nsw i32 1, %B
+  %D = srem i32 %C, %Y
+  %E = icmp slt i32 %D, 0
+  ret i1 %E
+}
+
+; CHECK: @srem4
+; CHECK-NEXT: ret i1 false
+define i1 @srem4(i16 %X, i32 %Y) {
+  %A = zext i16 %X to i32
+  %B = or i32 2147483648, %A
+  %C = sub nsw i32 %A, %B
+  %D = srem i32 %C, %Y
+  %E = icmp slt i32 %D, 0
+  ret i1 %E
+}
+
 define i1 @udiv1(i32 %X) {
 ; CHECK: @udiv1
   %A = udiv i32 %X, 1000000