summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2008-07-11 07:20:53 +0000
committerNick Lewycky <nicholas@mxc.ca>2008-07-11 07:20:53 +0000
commit4bf1e59819b3830efb9025673e43e928395fafd0 (patch)
treec6409e83081d8ad1227f80b9a235efd7c82b7059 /lib/Transforms/Scalar
parent71ca353ae686ce9249eb333a48f12c1e4d47a319 (diff)
downloadllvm-4bf1e59819b3830efb9025673e43e928395fafd0.tar.gz
llvm-4bf1e59819b3830efb9025673e43e928395fafd0.tar.bz2
llvm-4bf1e59819b3830efb9025673e43e928395fafd0.tar.xz
Add another optimization from PR2330. Also catch some missing cases that are
similar. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53451 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index e65cfacc81..727f7bdcd1 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/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))) &&