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!

llvm-svn: 127146
This commit is contained in:
Nick Lewycky 2011-03-07 01:50:10 +00:00
parent 7260d8f57b
commit e467979d0a
3 changed files with 44 additions and 0 deletions

View 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))) {

View 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);

View 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
}