summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2010-01-28 17:22:42 +0000
committerDuncan Sands <baldrick@free.fr>2010-01-28 17:22:42 +0000
commit3a48b87c54b2eda1aa0798e87ffea735f28d5e8b (patch)
treef4037395cb147f08017b840810039acfb41cb715 /llvm
parent2cb941642e87e07befed66cc96f36a4d37556911 (diff)
downloadbcm5719-llvm-3a48b87c54b2eda1aa0798e87ffea735f28d5e8b.tar.gz
bcm5719-llvm-3a48b87c54b2eda1aa0798e87ffea735f28d5e8b.zip
Fix PR6165. The bug was that LHSKnownZero was being and'd with DemandedMask
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. llvm-svn: 94745
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp13
-rw-r--r--llvm/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll19
2 files changed, 30 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 74a1b6803d4..ec1ed664961 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -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/llvm/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll b/llvm/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll
new file mode 100644
index 00000000000..4ab9bf0c3f5
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/2010-01-28-NegativeSRem.ll
@@ -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
+}
OpenPOWER on IntegriCloud