From f33151aff008c40eec6435ddb7a5c9017b6acef9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 8 May 2005 21:28:52 +0000 Subject: [PATCH] Teach reassociate that 0-X === X*-1 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21785 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/Reassociate.cpp | 50 ++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 188d0d35392..69589032264 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -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(LHS)); + LHSBO = isReassociableOp(LHS, Opcode); + } + if (!RHSBO && RHS->hasOneUse() && BinaryOperator::isNeg(RHS)) { + RHS = LowerNegateToMultiply(cast(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(BI->getOperand(1))) if (Instruction *NI = ConvertShiftToMul(BI)) {