teach instcombine to simplify xor's harder, catching the

new testcase.

llvm-svn: 83799
This commit is contained in:
Chris Lattner 2009-10-11 22:22:13 +00:00
parent d2dc77f8c0
commit b033a0ac47
2 changed files with 38 additions and 0 deletions

View File

@ -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;

View File

@ -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
}