diff options
author | Chris Lattner <sabre@nondot.org> | 2009-10-11 22:22:13 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-10-11 22:22:13 +0000 |
commit | eefa89c5b8ccf1a50ffeca3493d9608f3c3ae491 (patch) | |
tree | 158336f18267c0ef4bd47f7972233fbf55d11c72 /lib/Transforms | |
parent | 4580d45e185e24ae6460f55c8bd825b222881e25 (diff) | |
download | external_llvm-eefa89c5b8ccf1a50ffeca3493d9608f3c3ae491.zip external_llvm-eefa89c5b8ccf1a50ffeca3493d9608f3c3ae491.tar.gz external_llvm-eefa89c5b8ccf1a50ffeca3493d9608f3c3ae491.tar.bz2 |
teach instcombine to simplify xor's harder, catching the
new testcase.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 6d16666..dcb65a8 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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; |