diff options
| -rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 31 | ||||
| -rw-r--r-- | llvm/test/Transforms/Reassociate/basictest.ll | 13 | 
2 files changed, 43 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index d22b9bfc40b..bbb0e0a2dfc 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -376,6 +376,9 @@ void Reassociate::RewriteExprTree(BinaryOperator *I,  // that should be processed next by the reassociation pass.  //  static Value *NegateValue(Value *V, Instruction *BI) { +  if (Constant *C = dyn_cast<Constant>(V)) +    return ConstantExpr::getNeg(C); +      // We are trying to expose opportunity for reassociation.  One of the things    // that we want to do to achieve this is to push a negation as deep into an    // expression chain as possible, to expose the add instructions.  In practice, @@ -400,10 +403,36 @@ static Value *NegateValue(Value *V, Instruction *BI) {        I->setName(I->getName()+".neg");        return I;      } +   +  // Okay, we need to materialize a negated version of V with an instruction. +  // Scan the use lists of V to see if we have one already. +  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){ +    if (!BinaryOperator::isNeg(*UI)) continue; + +    // We found one!  Now we have to make sure that the definition dominates +    // this use.  We do this by moving it to the entry block (if it is a +    // non-instruction value) or right after the definition.  These negates will +    // be zapped by reassociate later, so we don't need much finesse here. +    BinaryOperator *TheNeg = cast<BinaryOperator>(*UI); +     +    BasicBlock::iterator InsertPt; +    if (Instruction *InstInput = dyn_cast<Instruction>(V)) { +      if (InvokeInst *II = dyn_cast<InvokeInst>(InstInput)) { +        InsertPt = II->getNormalDest()->begin(); +      } else { +        InsertPt = InstInput; +        ++InsertPt; +      } +      while (isa<PHINode>(InsertPt)) ++InsertPt; +    } else { +      InsertPt = TheNeg->getParent()->getParent()->getEntryBlock().begin(); +    } +    TheNeg->moveBefore(InsertPt); +    return TheNeg; +  }    // Insert a 'neg' instruction that subtracts the value from zero to get the    // negation. -  //    return BinaryOperator::CreateNeg(V, V->getName() + ".neg", BI);  } diff --git a/llvm/test/Transforms/Reassociate/basictest.ll b/llvm/test/Transforms/Reassociate/basictest.ll index af08b583bb4..0f137dc8add 100644 --- a/llvm/test/Transforms/Reassociate/basictest.ll +++ b/llvm/test/Transforms/Reassociate/basictest.ll @@ -165,4 +165,17 @@ define i32 @test11(i32 %W) {  ; CHECK-NEXT: ret i32  } +define i32 @test12(i32 %X) { +  %A = sub i32 1, %X +  %B = sub i32 2, %X +  %C = sub i32 3, %X + +  %Y = add i32 %A ,%B +  %Z = add i32 %Y, %C +  ret i32 %Z +; CHECK: @test12 +; CHECK-NEXT: mul i32 %X, -3 +; CHECK-NEXT: add i32{{.*}}, 6 +; CHECK-NEXT: ret i32 +}  | 

