aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-03-07 01:50:10 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-03-07 01:50:10 +0000
commitc14bc77315ac4867f16c1585181b41919339eb3c (patch)
treea5613a37365664d1bf1f6352f4e7fea7c0b4893b
parent128ccbb8e5e142d4ec6c9afb4160b74f76cb3064 (diff)
Add more analysis of the sign bit of an srem instruction. If the LHS is negative
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
-rw-r--r--lib/Analysis/ValueTracking.cpp13
-rw-r--r--lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp12
-rw-r--r--test/Transforms/InstCombine/icmp.ll19
3 files changed, 44 insertions, 0 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp
index 82f4f64fc6..231b95b618 100644
--- a/lib/Analysis/ValueTracking.cpp
+++ b/lib/Analysis/ValueTracking.cpp
@@ -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))) {
diff --git a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index bda8cea4e4..b12d4c3687 100644
--- a/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -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);
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 63f76313f8..bf0107adf0 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -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
+}