aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-07-23 19:36:21 +0000
committerChris Lattner <sabre@nondot.org>2003-07-23 19:36:21 +0000
commit06782f804f4d66dd748632da73d8d017bd19f04e (patch)
tree150c24539fd1be12cd05942d89695cdf8a7e21eb /lib/Transforms
parent4daaebf170a1b39bf3c2d43a690ceb94165708f3 (diff)
downloadexternal_llvm-06782f804f4d66dd748632da73d8d017bd19f04e.zip
external_llvm-06782f804f4d66dd748632da73d8d017bd19f04e.tar.gz
external_llvm-06782f804f4d66dd748632da73d8d017bd19f04e.tar.bz2
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp20
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 7054661..32a2d62 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);