InstCombine: Canonicalize (2^n)-1 - x into (2^n)-1 ^ x iff x is known to be smaller than 2^n.

This has the obvious advantage of being commutable and is always a win on x86 because
const - x wastes a register there. On less weird architectures this may lead to
a regression because other arithmetic doesn't fuse with it anymore. I'll address that
problem in a followup.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147254 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2011-12-24 17:31:38 +00:00
parent ce618af3e8
commit 1fdfae05b0
3 changed files with 26 additions and 0 deletions

View File

@ -587,6 +587,9 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
ConstantInt *C2;
if (match(Op1, m_Add(m_Value(X), m_ConstantInt(C2))))
return BinaryOperator::CreateSub(ConstantExpr::getSub(C, C2), X);
if (SimplifyDemandedInstructionBits(I))
return &I;
}

View File

@ -567,9 +567,20 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
LHSKnownZero, LHSKnownOne, Depth+1))
return I;
}
// Otherwise just hand the sub off to ComputeMaskedBits to fill in
// the known zeros and ones.
ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth);
// Turn this into a xor if LHS is 2^n-1 and the remaining bits are known
// zero.
if (ConstantInt *C0 = dyn_cast<ConstantInt>(I->getOperand(0))) {
APInt I0 = C0->getValue();
if ((I0 + 1).isPowerOf2() && (I0 | KnownZero).isAllOnesValue()) {
Instruction *Xor = BinaryOperator::CreateXor(I->getOperand(1), C0);
return InsertNewInstWith(Xor, *I);
}
}
break;
case Instruction::Shl:
if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {

View File

@ -0,0 +1,12 @@
; RUN: opt -instcombine -S < %s | FileCheck %s
define i32 @test1(i32 %x) nounwind {
%and = and i32 %x, 31
%sub = sub i32 63, %and
ret i32 %sub
; CHECK: @test1
; CHECK-NEXT: and i32 %x, 31
; CHECK-NEXT: xor i32 %and, 63
; CHECK-NEXT: ret
}