Teach reassociate that 0-X === X*-1
authorChris Lattner <sabre@nondot.org>
Sun, 8 May 2005 21:28:52 +0000 (21:28 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 8 May 2005 21:28:52 +0000 (21:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21785 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/Reassociate.cpp

index 188d0d353922909d21c671f5cdaec167f59bb41c..695890322646f25b713dda9b16756319f9d558dd 100644 (file)
@@ -152,6 +152,23 @@ static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode) {
   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 @@ void Reassociate::LinearizeExprTree(BinaryOperator *I,
   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 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {
   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)) {