mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-29 07:53:33 +00:00
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:
parent
ce618af3e8
commit
1fdfae05b0
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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))) {
|
||||
|
12
test/Transforms/InstCombine/sub-xor.ll
Normal file
12
test/Transforms/InstCombine/sub-xor.ll
Normal 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
|
||||
}
|
Loading…
Reference in New Issue
Block a user