summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2008-02-03 07:42:09 +0000
committerNick Lewycky <nicholas@mxc.ca>2008-02-03 07:42:09 +0000
commite6e3a7f6ea75524c4c7c2805e06d0f20a18a8a7a (patch)
treee12f11269768a787a9671785800088747e684c20
parentc41e535df1fda07059795368d1c114dda5da971d (diff)
downloadbcm5719-llvm-e6e3a7f6ea75524c4c7c2805e06d0f20a18a8a7a.tar.gz
bcm5719-llvm-e6e3a7f6ea75524c4c7c2805e06d0f20a18a8a7a.zip
Fold away one multiply in instcombine. This would normally be caught in
reassociate anyways, but they could be generated during instcombine's run. llvm-svn: 46683
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 1968f9b36ef..761b57d2ec7 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -2123,6 +2123,30 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2)))
return R;
+ // W*X + Y*Z --> W * (X+Z) iff W == Y
+ if (I.getType()->isInteger()) {
+ Value *W, *X, *Y, *Z;
+ if (match(LHS, m_Mul(m_Value(W), m_Value(X))) &&
+ match(RHS, m_Mul(m_Value(Y), m_Value(Z)))) {
+ if (W != Y) {
+ if (W == Z) {
+ std::swap(Y, Z);
+ } else if (Y == X) {
+ std::swap(W, X);
+ } else if (X == Z) {
+ std::swap(Y, Z);
+ std::swap(W, X);
+ }
+ }
+
+ if (W == Y) {
+ Value *NewAdd = InsertNewInstBefore(BinaryOperator::createAdd(X, Z,
+ LHS->getName()), I);
+ return BinaryOperator::createMul(W, NewAdd);
+ }
+ }
+ }
+
if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
Value *X = 0;
if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X
OpenPOWER on IntegriCloud