diff options
author | Chris Lattner <sabre@nondot.org> | 2003-07-23 19:25:52 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-07-23 19:25:52 +0000 |
commit | 16464b36ffde43fcbb708b4c55b992deaaba8e60 (patch) | |
tree | b8831e691aa3be743f7d0cb64c022e948dc1a688 /llvm/lib/Transforms/Scalar | |
parent | fcd1efbbc0df15cf430f092b3443df984143f5e9 (diff) | |
download | bcm5719-llvm-16464b36ffde43fcbb708b4c55b992deaaba8e60.tar.gz bcm5719-llvm-16464b36ffde43fcbb708b4c55b992deaaba8e60.zip |
- InstCombine: (X | C1) & C2 --> X & C2 iff C1 & C1 == 0
- InstCombine: (X | C) & C --> C
- InstCombine: (X | C1) & C2 --> (X | (C1&C2)) & C2
llvm-svn: 7269
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
-rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index df0b3566bee..70546612449 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -497,16 +497,39 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); - // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) - if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) - if (Op0I->getOpcode() == Instruction::Xor && isOnlyUse(Op0)) - if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) { - std::string Op0Name = Op0I->getName(); Op0I->setName(""); - Instruction *And = BinaryOperator::create(Instruction::And, - Op0I->getOperand(0), RHS, - Op0Name); - InsertNewInstBefore(And, I); - return BinaryOperator::create(Instruction::Xor, And, *RHS & *Op0CI); + if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) + if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) + if (Op0I->getOpcode() == Instruction::Xor) { + 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); + 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); + + Constant *Together = *RHS & *Op0CI; + if (Together == RHS) // (X | C) & C --> C + return ReplaceInstUsesWith(I, RHS); + + if (isOnlyUse(Op0)) { + 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); + InsertNewInstBefore(Or, I); + return BinaryOperator::create(Instruction::And, Or, RHS); + } + } } } |