Try once again to optimize "icmp (srem X, Y), Y" by turning the comparison into

true/false or "icmp slt/sge Y, 0".


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127063 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2011-03-05 04:28:48 +00:00
parent 874be74179
commit 9feda1730c
2 changed files with 45 additions and 0 deletions

View File

@ -2314,6 +2314,35 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
BO0->hasOneUse() && BO1->hasOneUse())
return new ICmpInst(Pred, D, B);
BinaryOperator *SRem = NULL;
// icmp Y, (srem X, Y)
if (BO0 && BO0->getOpcode() == Instruction::SRem &&
Op1 == BO0->getOperand(1))
SRem = BO0;
// icmp (srem X, Y), Y
else if (BO1 && BO1->getOpcode() == Instruction::SRem &&
Op0 == BO1->getOperand(1))
SRem = BO1;
if (SRem) {
// We don't check hasOneUse to avoid increasing register pressure because
// the value we use is the same value this instruction was already using.
switch (SRem == BO0 ? ICmpInst::getSwappedPredicate(Pred) : Pred) {
default: break;
case ICmpInst::ICMP_EQ:
return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getContext()));
case ICmpInst::ICMP_NE:
return ReplaceInstUsesWith(I, ConstantInt::getTrue(I.getContext()));
case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_SGE:
return new ICmpInst(ICmpInst::ICMP_SGT, SRem->getOperand(1),
Constant::getAllOnesValue(SRem->getType()));
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_SLE:
return new ICmpInst(ICmpInst::ICMP_SLT, SRem->getOperand(1),
Constant::getNullValue(SRem->getType()));
}
}
if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() &&
BO0->hasOneUse() && BO1->hasOneUse() &&
BO0->getOperand(1) == BO1->getOperand(1)) {

View File

@ -403,3 +403,19 @@ define i1 @test41(i32 %X, i32 %Y) {
%B = icmp ugt i32 %Y, %A
ret i1 %B
}
; CHECK: @test42
; CHECK: %B = icmp sgt i32 %Y, -1
define i1 @test42(i32 %X, i32 %Y) {
%A = srem i32 %X, %Y
%B = icmp slt i32 %A, %Y
ret i1 %B
}
; CHECK: @test43
; CHECK: %B = icmp slt i32 %Y, 0
define i1 @test43(i32 %X, i32 %Y) {
%A = srem i32 %X, %Y
%B = icmp slt i32 %Y, %A
ret i1 %B
}