From 9feda1730c225589e144fb1f86a86a8cf3f39c9e Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sat, 5 Mar 2011 04:28:48 +0000 Subject: [PATCH] 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 --- .../InstCombine/InstCombineCompares.cpp | 29 +++++++++++++++++++ test/Transforms/InstCombine/icmp.ll | 16 ++++++++++ 2 files changed, 45 insertions(+) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index fe117c98143..239cd23a2c6 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -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)) { diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index fba273550b1..fb43e594535 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -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 +}