diff options
author | Chris Lattner <sabre@nondot.org> | 2003-07-23 19:36:21 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-07-23 19:36:21 +0000 |
commit | 06782f804f4d66dd748632da73d8d017bd19f04e (patch) | |
tree | 150c24539fd1be12cd05942d89695cdf8a7e21eb | |
parent | 4daaebf170a1b39bf3c2d43a690ceb94165708f3 (diff) |
InstCombine: (X ^ C1) & C2 --> (X & C2) iff (C1&C2) == 0
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7272 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 7054661244..32a2d6251f 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -497,23 +497,25 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); - if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) + if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) { + Value *X = Op0I->getOperand(0); if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) if (Op0I->getOpcode() == Instruction::Xor) { - if (isOnlyUse(Op0)) { + if ((*RHS & *Op0CI)->isNullValue()) { + // (X ^ C1) & C2 --> (X & C2) iff (C1&C2) == 0 + return BinaryOperator::create(Instruction::And, X, RHS); + } else if (isOnlyUse(Op0)) { // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) std::string Op0Name = Op0I->getName(); Op0I->setName(""); Instruction *And = BinaryOperator::create(Instruction::And, - Op0I->getOperand(0), RHS, - Op0Name); + X, RHS, Op0Name); InsertNewInstBefore(And, I); return BinaryOperator::create(Instruction::Xor, And, *RHS & *Op0CI); } } else if (Op0I->getOpcode() == Instruction::Or) { // (X | C1) & C2 --> X & C2 iff C1 & C1 == 0 if ((*RHS & *Op0CI)->isNullValue()) - return BinaryOperator::create(Instruction::And, Op0I->getOperand(0), - RHS); + return BinaryOperator::create(Instruction::And, X, RHS); Constant *Together = *RHS & *Op0CI; if (Together == RHS) // (X | C) & C --> C @@ -523,14 +525,14 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (Together != Op0CI) { // (X | C1) & C2 --> (X | (C1&C2)) & C2 std::string Op0Name = Op0I->getName(); Op0I->setName(""); - Instruction *Or = BinaryOperator::create(Instruction::Or, - Op0I->getOperand(0), - Together, Op0Name); + Instruction *Or = BinaryOperator::create(Instruction::Or, X, + Together, Op0Name); InsertNewInstBefore(Or, I); return BinaryOperator::create(Instruction::And, Or, RHS); } } } + } } Value *Op0NotVal = dyn_castNotVal(Op0); |