summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-07-23 18:29:44 +0000
committerChris Lattner <sabre@nondot.org>2003-07-23 18:29:44 +0000
commit8f0d15601a95e9005614997e441aabf104b8d01b (patch)
tree89744a6349fc6fd7c721f215ee72fde440c0c716 /llvm/lib/Transforms/Scalar/InstructionCombining.cpp
parentd5663230b420531b0ffa4416ded816d93c67d7bb (diff)
downloadbcm5719-llvm-8f0d15601a95e9005614997e441aabf104b8d01b.tar.gz
bcm5719-llvm-8f0d15601a95e9005614997e441aabf104b8d01b.zip
IC: (X & C1) | C2 --> (X | C2) & (C1|C2)
IC: (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2) We are now guaranteed that all 'or's will be inside of 'and's, and all 'and's will be inside of 'xor's, if the second operands are constants. llvm-svn: 7264
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 1ace95f28bb..df0b3566bee 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -538,10 +538,35 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
return ReplaceInstUsesWith(I, Op0);
// or X, -1 == -1
- if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1))
+ if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
if (RHS->isAllOnesValue())
return ReplaceInstUsesWith(I, Op1);
+ if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) {
+ // (X & C1) | C2 --> (X | C2) & (C1|C2)
+ if (Op0I->getOpcode() == Instruction::And && isOnlyUse(Op0))
+ if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
+ std::string Op0Name = Op0I->getName(); Op0I->setName("");
+ Instruction *Or = BinaryOperator::create(Instruction::Or,
+ Op0I->getOperand(0), RHS,
+ Op0Name);
+ InsertNewInstBefore(Or, I);
+ return BinaryOperator::create(Instruction::And, Or, *RHS | *Op0CI);
+ }
+
+ // (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
+ if (Op0I->getOpcode() == Instruction::Xor && isOnlyUse(Op0))
+ if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
+ std::string Op0Name = Op0I->getName(); Op0I->setName("");
+ Instruction *Or = BinaryOperator::create(Instruction::Or,
+ Op0I->getOperand(0), RHS,
+ Op0Name);
+ InsertNewInstBefore(Or, I);
+ return BinaryOperator::create(Instruction::Xor, Or, *Op0CI & *~*RHS);
+ }
+ }
+ }
+
Value *Op0NotVal = dyn_castNotVal(Op0);
Value *Op1NotVal = dyn_castNotVal(Op1);
OpenPOWER on IntegriCloud