mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-05 02:07:16 +00:00
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
This commit is contained in:
parent
71ca353ae6
commit
4bf1e59819
@ -5480,6 +5480,45 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
|||||||
return R;
|
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
|
// ~x < ~y --> y < x
|
||||||
{ Value *A, *B;
|
{ Value *A, *B;
|
||||||
if (match(Op0, m_Not(m_Value(A))) &&
|
if (match(Op0, m_Not(m_Value(A))) &&
|
||||||
|
19
test/Transforms/InstCombine/2008-07-10-ICmpBinOp.ll
Normal file
19
test/Transforms/InstCombine/2008-07-10-ICmpBinOp.ll
Normal file
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user