OSDN Git Service

Fix PR6165. The bug was that LHSKnownZero was being and'd with DemandedMask
authorDuncan Sands <baldrick@free.fr>
Thu, 28 Jan 2010 17:22:42 +0000 (17:22 +0000)
committerDuncan Sands <baldrick@free.fr>
Thu, 28 Jan 2010 17:22:42 +0000 (17:22 +0000)
when it should have been and'd with LowBits.  Fix that and while there beef
up the logic in the case of a negative LHS.

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

lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll [new file with mode: 0644]

index 74a1b68..ec1ed66 100644 (file)
@@ -681,10 +681,19 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
                                  LHSKnownZero, LHSKnownOne, Depth+1))
           return I;
 
+        // The low bits of LHS are unchanged by the srem.
+        KnownZero |= LHSKnownZero & LowBits;
+        KnownOne |= LHSKnownOne & LowBits;
+
+        // If LHS is non-negative or has all low bits zero, then the upper bits
+        // are all zero.
         if (LHSKnownZero[BitWidth-1] || ((LHSKnownZero & LowBits) == LowBits))
-          LHSKnownZero |= ~LowBits;
+          KnownZero |= ~LowBits;
 
-        KnownZero |= LHSKnownZero & DemandedMask;
+        // If LHS is negative and not all low bits are zero, then the upper bits
+        // are all one.
+        if (LHSKnownOne[BitWidth-1] && ((LHSKnownOne & LowBits) != 0))
+          KnownOne |= ~LowBits;
 
         assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?"); 
       }
diff --git a/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll b/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll
new file mode 100644 (file)
index 0000000..4ab9bf0
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; PR6165
+
+define i32 @f() {
+entry:
+  br label %BB1
+
+BB1:                                              ; preds = %BB1, %entry
+; CHECK: BB1:
+  %x = phi i32 [ -29, %entry ], [ 0, %BB1 ]       ; <i32> [#uses=2]
+  %rem = srem i32 %x, 2                           ; <i32> [#uses=1]
+  %t = icmp eq i32 %rem, -1                       ; <i1> [#uses=1]
+  br i1 %t, label %BB2, label %BB1
+; CHECK-NOT: br i1 false
+
+BB2:                                              ; preds = %BB1
+; CHECK: BB2:
+  ret i32 %x
+}