summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-07-23 19:25:52 +0000
committerChris Lattner <sabre@nondot.org>2003-07-23 19:25:52 +0000
commit16464b36ffde43fcbb708b4c55b992deaaba8e60 (patch)
treeb8831e691aa3be743f7d0cb64c022e948dc1a688 /llvm/lib/Transforms/Scalar
parentfcd1efbbc0df15cf430f092b3443df984143f5e9 (diff)
downloadbcm5719-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.cpp43
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);
+ }
+ }
}
}
OpenPOWER on IntegriCloud