diff options
| author | Nick Lewycky <nicholas@mxc.ca> | 2008-07-11 07:20:53 +0000 |
|---|---|---|
| committer | Nick Lewycky <nicholas@mxc.ca> | 2008-07-11 07:20:53 +0000 |
| commit | f95b64acaa98786690f1b45158cc5bd63589d258 (patch) | |
| tree | a26b74ea98ef845b73018350cfbec356ed4f38c5 /llvm | |
| parent | 5774466a3323459e3b9843546cf173e4066eda35 (diff) | |
| download | bcm5719-llvm-f95b64acaa98786690f1b45158cc5bd63589d258.tar.gz bcm5719-llvm-f95b64acaa98786690f1b45158cc5bd63589d258.zip | |
Add another optimization from PR2330. Also catch some missing cases that are
similar.
llvm-svn: 53451
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 39 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/2008-07-10-ICmpBinOp.ll | 19 |
2 files changed, 58 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index e65cfacc81e..727f7bdcd1e 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -5480,6 +5480,45 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { return R; } + // See if it's the same type of instruction on the left and right. + if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) { + if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1)) { + if (Op0I->getOpcode() == Op1I->getOpcode() && Op0I->hasOneUse() && + Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1) && + I.isEquality()) { + switch (Op0I->getOpcode()) { + default: break; + case Instruction::Add: + case Instruction::Sub: + case Instruction::Xor: + // a+x icmp eq/ne b+x --> a icmp b + return new ICmpInst(I.getPredicate(), Op0I->getOperand(0), + Op1I->getOperand(0)); + break; + case Instruction::Mul: + if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) { + // a * Cst icmp eq/ne b * Cst --> a & 0x7f icmp b & 0x7f + if (!CI->isZero() && !CI->isOne()) { + const APInt &AP = CI->getValue(); + ConstantInt *Mask = ConstantInt::get( + APInt::getLowBitsSet(AP.getBitWidth(), + AP.getBitWidth() - + AP.countTrailingZeros())); + Instruction *And1 = BinaryOperator::CreateAnd(Op0I->getOperand(0), + Mask); + Instruction *And2 = BinaryOperator::CreateAnd(Op1I->getOperand(0), + Mask); + InsertNewInstBefore(And1, I); + InsertNewInstBefore(And2, I); + return new ICmpInst(I.getPredicate(), And1, And2); + } + } + break; + } + } + } + } + // ~x < ~y --> y < x { Value *A, *B; if (match(Op0, m_Not(m_Value(A))) && diff --git a/llvm/test/Transforms/InstCombine/2008-07-10-ICmpBinOp.ll b/llvm/test/Transforms/InstCombine/2008-07-10-ICmpBinOp.ll new file mode 100644 index 00000000000..50533db06d5 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2008-07-10-ICmpBinOp.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep add +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep mul +; PR2330 + +define i1 @f(i32 %x, i32 %y) nounwind { +entry: + %A = add i32 %x, 5 + %B = add i32 %y, 5 + %C = icmp eq i32 %A, %B + ret i1 %C +} + +define i1 @g(i32 %x, i32 %y) nounwind { +entry: + %A = mul i32 %x, 5 + %B = mul i32 %y, 5 + %C = icmp eq i32 %A, %B + ret i1 %C +} |

