Reinstate this optimization to fold icmp of xor when possible. Don't try to

turn icmp eq a+x, b+x into icmp eq a, b if a+x or b+x has other uses. This
may have been increasing register pressure leading to the bzip2 slowdown.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63487 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2009-01-31 21:30:05 +00:00
parent 35ba3d4638
commit 4333f49afe
3 changed files with 72 additions and 6 deletions

View File

@ -6095,18 +6095,40 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
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()) {
Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1)) {
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));
if (I.isEquality()) {
// a+x icmp eq/ne b+x --> a icmp b
return new ICmpInst(I.getPredicate(), Op0I->getOperand(0),
Op1I->getOperand(0));
} else {
// icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
if (CI->getValue().isSignBit()) {
ICmpInst::Predicate Pred = I.isSignedPredicate()
? I.getUnsignedPredicate()
: I.getSignedPredicate();
return new ICmpInst(Pred, Op0I->getOperand(0),
Op1I->getOperand(0));
} else if ((~CI->getValue()).isSignBit()) {
ICmpInst::Predicate Pred = I.isSignedPredicate()
? I.getUnsignedPredicate()
: I.getSignedPredicate();
Pred = I.getSwappedPredicate(Pred);
return new ICmpInst(Pred, Op0I->getOperand(0),
Op1I->getOperand(0));
}
}
}
break;
case Instruction::Mul:
if (!I.isEquality())
break;
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
// a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask
// Mask = -1 >> count-trailing-zeros(Cst).
@ -6425,6 +6447,29 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
else
return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS));
}
if (LHSI->hasOneUse()) {
// (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit))
if (!ICI.isEquality() && XorCST->getValue().isSignBit()) {
const APInt &SignBit = XorCST->getValue();
ICmpInst::Predicate Pred = ICI.isSignedPredicate()
? ICI.getUnsignedPredicate()
: ICI.getSignedPredicate();
return new ICmpInst(Pred, LHSI->getOperand(0),
ConstantInt::get(RHSV ^ SignBit));
}
// (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A)
if (!ICI.isEquality() && (~XorCST->getValue()).isSignBit()) {
const APInt &NotSignBit = XorCST->getValue();
ICmpInst::Predicate Pred = ICI.isSignedPredicate()
? ICI.getUnsignedPredicate()
: ICI.getSignedPredicate();
Pred = ICI.getSwappedPredicate(Pred);
return new ICmpInst(Pred, LHSI->getOperand(0),
ConstantInt::get(RHSV ^ NotSignBit));
}
}
}
break;
case Instruction::And: // (icmp pred (and X, AndCST), RHS)

View File

@ -1,5 +1,4 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep xor
; XFAIL: *
define i1 @test1(i8 %x, i8 %y) {
%X = xor i8 %x, 128

View File

@ -0,0 +1,22 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {%B = add i8 %b, %x}
; PR2698
declare void @use1(i1)
declare void @use8(i8)
define void @test1(i8 %a, i8 %b, i8 %x) {
%A = add i8 %a, %x
%B = add i8 %b, %x
%C = icmp eq i8 %A, %B
call void @use1(i1 %C)
ret void
}
define void @test2(i8 %a, i8 %b, i8 %x) {
%A = add i8 %a, %x
%B = add i8 %b, %x
%C = icmp eq i8 %A, %B
call void @use1(i1 %C)
call void @use8(i8 %A)
ret void
}