[llvm-commits] CVS: llvm/lib/Transforms/Scalar/Reassociate.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun May 8 14:29:05 PDT 2005



Changes in directory llvm/lib/Transforms/Scalar:

Reassociate.cpp updated: 1.45 -> 1.46
---
Log message:

Teach reassociate that 0-X === X*-1


---
Diffs of the changes:  (+46 -4)

 Reassociate.cpp |   50 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 46 insertions(+), 4 deletions(-)


Index: llvm/lib/Transforms/Scalar/Reassociate.cpp
diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.45 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.46
--- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.45	Sun May  8 15:57:04 2005
+++ llvm/lib/Transforms/Scalar/Reassociate.cpp	Sun May  8 16:28:52 2005
@@ -152,6 +152,23 @@
   return 0;
 }
 
+/// LowerNegateToMultiply - Replace 0-X with X*-1.
+///
+static Instruction *LowerNegateToMultiply(Instruction *Neg) {
+  Constant *Cst;
+  if (Neg->getType()->isFloatingPoint())
+    Cst = ConstantFP::get(Neg->getType(), -1);
+  else
+    Cst = ConstantInt::getAllOnesValue(Neg->getType());
+
+  std::string NegName = Neg->getName(); Neg->setName("");
+  Instruction *Res = BinaryOperator::createMul(Neg->getOperand(1), Cst, NegName,
+                                               Neg);
+  Neg->replaceAllUsesWith(Res);
+  Neg->eraseFromParent();
+  return Res;
+}
+
 // Given an expression of the form '(A+B)+(D+C)', turn it into '(((A+B)+C)+D)'.
 // Note that if D is also part of the expression tree that we recurse to
 // linearize it as well.  Besides that case, this does not recurse into A,B, or
@@ -201,6 +218,19 @@
   BinaryOperator *LHSBO = isReassociableOp(LHS, Opcode);
   BinaryOperator *RHSBO = isReassociableOp(RHS, Opcode);
 
+  // If this is a multiply expression tree and it contains internal negations,
+  // transform them into multiplies by -1 so they can be reassociated.
+  if (I->getOpcode() == Instruction::Mul) {
+    if (!LHSBO && LHS->hasOneUse() && BinaryOperator::isNeg(LHS)) {
+      LHS = LowerNegateToMultiply(cast<Instruction>(LHS));
+      LHSBO = isReassociableOp(LHS, Opcode);
+    }
+    if (!RHSBO && RHS->hasOneUse() && BinaryOperator::isNeg(RHS)) {
+      RHS = LowerNegateToMultiply(cast<Instruction>(RHS));
+      RHSBO = isReassociableOp(RHS, Opcode);
+    }
+  }
+
   if (!LHSBO) {
     if (!RHSBO) {
       // Neither the LHS or RHS as part of the tree, thus this is a leaf.  As
@@ -532,11 +562,23 @@
   for (BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI) {
     // If this is a subtract instruction which is not already in negate form,
     // see if we can convert it to X+-Y.
-    if (BI->getOpcode() == Instruction::Sub && !BinaryOperator::isNeg(BI))
-      if (Instruction *NI = BreakUpSubtract(BI)) {
-        MadeChange = true;
-        BI = NI;
+    if (BI->getOpcode() == Instruction::Sub) {
+      if (!BinaryOperator::isNeg(BI)) {
+        if (Instruction *NI = BreakUpSubtract(BI)) {
+          MadeChange = true;
+          BI = NI;
+        }
+      } else {
+        // Otherwise, this is a negation.  See if the operand is a multiply tree
+        // and if this is not an inner node of a multiply tree.
+        if (isReassociableOp(BI->getOperand(1), Instruction::Mul) &&
+            (!BI->hasOneUse() ||
+             !isReassociableOp(BI->use_back(), Instruction::Mul))) {
+          BI = LowerNegateToMultiply(BI);
+          MadeChange = true;
+        }
       }
+    }
     if (BI->getOpcode() == Instruction::Shl &&
         isa<ConstantInt>(BI->getOperand(1)))
       if (Instruction *NI = ConvertShiftToMul(BI)) {






More information about the llvm-commits mailing list