mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-26 13:36:28 +00:00
teach instcombine to simplify xor's harder, catching the
new testcase. llvm-svn: 83799
This commit is contained in:
parent
d2dc77f8c0
commit
b033a0ac47
@ -1047,6 +1047,33 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
|
||||
if (ShrinkDemandedConstant(I, 1, DemandedMask))
|
||||
return I;
|
||||
|
||||
// If our LHS is an 'and' and if it has one use, and if any of the bits we
|
||||
// are flipping are known to be set, then the xor is just resetting those
|
||||
// bits to zero. We can just knock out bits from the 'and' and the 'xor',
|
||||
// simplifying both of them.
|
||||
if (Instruction *LHSInst = dyn_cast<Instruction>(I->getOperand(0)))
|
||||
if (LHSInst->getOpcode() == Instruction::And && LHSInst->hasOneUse() &&
|
||||
isa<ConstantInt>(I->getOperand(1)) &&
|
||||
isa<ConstantInt>(LHSInst->getOperand(1)) &&
|
||||
(LHSKnownOne & RHSKnownOne & DemandedMask) != 0) {
|
||||
ConstantInt *AndRHS = cast<ConstantInt>(LHSInst->getOperand(1));
|
||||
ConstantInt *XorRHS = cast<ConstantInt>(I->getOperand(1));
|
||||
APInt NewMask = ~(LHSKnownOne & RHSKnownOne & DemandedMask);
|
||||
|
||||
Constant *AndC =
|
||||
ConstantInt::get(I->getType(), NewMask & AndRHS->getValue());
|
||||
Instruction *NewAnd =
|
||||
BinaryOperator::CreateAnd(I->getOperand(0), AndC, "tmp");
|
||||
InsertNewInstBefore(NewAnd, *I);
|
||||
|
||||
Constant *XorC =
|
||||
ConstantInt::get(I->getType(), NewMask & XorRHS->getValue());
|
||||
Instruction *NewXor =
|
||||
BinaryOperator::CreateXor(NewAnd, XorC, "tmp");
|
||||
return InsertNewInstBefore(NewXor, *I);
|
||||
}
|
||||
|
||||
|
||||
RHSKnownZero = KnownZeroOut;
|
||||
RHSKnownOne = KnownOneOut;
|
||||
break;
|
||||
|
@ -30,3 +30,14 @@ define i32 @test2(i32 %tmp1) {
|
||||
%ov110 = xor i32 %ov3, 153
|
||||
ret i32 %ov110
|
||||
}
|
||||
|
||||
define i32 @test3(i32 %tmp1) {
|
||||
; CHECK: @test3
|
||||
; CHECK-NEXT: or i32 %tmp1, 8
|
||||
; CHECK-NEXT: and i32
|
||||
; CHECK-NEXT: ret i32
|
||||
%ovm = or i32 %tmp1, 145
|
||||
%ov31 = and i32 %ovm, 177
|
||||
%ov110 = xor i32 %ov31, 153
|
||||
ret i32 %ov110
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user