aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-02-18 19:57:07 +0000
committerChris Lattner <sabre@nondot.org>2003-02-18 19:57:07 +0000
commitad3448c91733f14866821c1e5d24ef2ce389a358 (patch)
tree56c069ee471240f2358f3931db0b4b68d7616b1f
parentfa59079c3c39e895c882a3d190f56bda365b96ab (diff)
4 new transformations:
* X*C + X --> X * (C+1) * X + X*C --> X * (C+1) * X - X*C --> X * (1-C) * X*C - X --> X * (C-1) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5592 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 0c46a7b223..f652e2bbc7 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -146,6 +146,16 @@ static unsigned Log2(uint64_t Val) {
return Count;
}
+static inline Value *dyn_castFoldableMul(Value *V) {
+ if (V->use_size() == 1 && V->getType()->isInteger())
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ if (I->getOpcode() == Instruction::Mul)
+ if (isa<Constant>(I->getOperand(1)))
+ return I->getOperand(0);
+ return 0;
+}
+
+
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
bool Changed = SimplifyBinOp(I);
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
@@ -182,6 +192,22 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
}
}
+ // X*C + X --> X * (C+1)
+ if (dyn_castFoldableMul(LHS) == RHS) {
+ Constant *CP1 = *cast<Constant>(cast<Instruction>(LHS)->getOperand(1)) +
+ *ConstantInt::get(I.getType(), 1);
+ assert(CP1 && "Couldn't constant fold C + 1?");
+ return BinaryOperator::create(Instruction::Mul, RHS, CP1);
+ }
+
+ // X + X*C --> X * (C+1)
+ if (dyn_castFoldableMul(RHS) == LHS) {
+ Constant *CP1 = *cast<Constant>(cast<Instruction>(RHS)->getOperand(1)) +
+ *ConstantInt::get(I.getType(), 1);
+ assert(CP1 && "Couldn't constant fold C + 1?");
+ return BinaryOperator::create(Instruction::Mul, LHS, CP1);
+ }
+
return Changed ? &I : 0;
}
@@ -231,8 +257,24 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Instruction *NewNot = BinaryOperator::createNot(OtherOp, "B.not", &I);
return BinaryOperator::create(Instruction::And, Op0, NewNot);
}
+
+ // X - X*C --> X * (1-C)
+ if (dyn_castFoldableMul(Op1I) == Op0) {
+ Constant *CP1 = *ConstantInt::get(I.getType(), 1) -
+ *cast<Constant>(cast<Instruction>(Op1)->getOperand(1));
+ assert(CP1 && "Couldn't constant fold 1-C?");
+ return BinaryOperator::create(Instruction::Mul, Op0, CP1);
+ }
}
+ // X*C - X --> X * (C-1)
+ if (dyn_castFoldableMul(Op0) == Op1) {
+ Constant *CP1 = *cast<Constant>(cast<Instruction>(Op0)->getOperand(1)) -
+ *ConstantInt::get(I.getType(), 1);
+ assert(CP1 && "Couldn't constant fold C - 1?");
+ return BinaryOperator::create(Instruction::Mul, Op1, CP1);
+ }
+
return 0;
}