OSDN Git Service

Fold away one multiply in instcombine. This would normally be caught in
authorNick Lewycky <nicholas@mxc.ca>
Sun, 3 Feb 2008 07:42:09 +0000 (07:42 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sun, 3 Feb 2008 07:42:09 +0000 (07:42 +0000)
reassociate anyways, but they could be generated during instcombine's run.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46683 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index 1968f9b..761b57d 100644 (file)
@@ -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