diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/Reassociate.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 309 |
1 files changed, 228 insertions, 81 deletions
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index ea2cf7cf9b5..b11567cc9df 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -240,6 +240,15 @@ static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode) { return nullptr; } +static BinaryOperator *isReassociableOp(Value *V, unsigned Opcode1, + unsigned Opcode2) { + if (V->hasOneUse() && isa<Instruction>(V) && + (cast<Instruction>(V)->getOpcode() == Opcode1 || + cast<Instruction>(V)->getOpcode() == Opcode2)) + return cast<BinaryOperator>(V); + return nullptr; +} + static bool isUnmovableInstruction(Instruction *I) { switch (I->getOpcode()) { case Instruction::PHI: @@ -304,8 +313,10 @@ unsigned Reassociate::getRank(Value *V) { // If this is a not or neg instruction, do not count it for rank. This // assures us that X and ~X will have the same rank. - if (!I->getType()->isIntegerTy() || - (!BinaryOperator::isNot(I) && !BinaryOperator::isNeg(I))) + Type *Ty = V->getType(); + if ((!Ty->isIntegerTy() && !Ty->isFloatingPointTy()) || + (!BinaryOperator::isNot(I) && !BinaryOperator::isNeg(I) && + !BinaryOperator::isFNeg(I))) ++Rank; //DEBUG(dbgs() << "Calculated Rank[" << V->getName() << "] = " @@ -314,14 +325,50 @@ unsigned Reassociate::getRank(Value *V) { return ValueRankMap[I] = Rank; } +static BinaryOperator *CreateAdd(Value *S1, Value *S2, const Twine &Name, + Instruction *InsertBefore, Value *FlagsOp) { + if (S1->getType()->isIntegerTy()) + return BinaryOperator::CreateAdd(S1, S2, Name, InsertBefore); + else { + BinaryOperator *Res = + BinaryOperator::CreateFAdd(S1, S2, Name, InsertBefore); + Res->setFastMathFlags(cast<FPMathOperator>(FlagsOp)->getFastMathFlags()); + return Res; + } +} + +static BinaryOperator *CreateMul(Value *S1, Value *S2, const Twine &Name, + Instruction *InsertBefore, Value *FlagsOp) { + if (S1->getType()->isIntegerTy()) + return BinaryOperator::CreateMul(S1, S2, Name, InsertBefore); + else { + BinaryOperator *Res = + BinaryOperator::CreateFMul(S1, S2, Name, InsertBefore); + Res->setFastMathFlags(cast<FPMathOperator>(FlagsOp)->getFastMathFlags()); + return Res; + } +} + +static BinaryOperator *CreateNeg(Value *S1, const Twine &Name, + Instruction *InsertBefore, Value *FlagsOp) { + if (S1->getType()->isIntegerTy()) + return BinaryOperator::CreateNeg(S1, Name, InsertBefore); + else { + BinaryOperator *Res = BinaryOperator::CreateFNeg(S1, Name, InsertBefore); + Res->setFastMathFlags(cast<FPMathOperator>(FlagsOp)->getFastMathFlags()); + return Res; + } +} + /// LowerNegateToMultiply - Replace 0-X with X*-1. /// static BinaryOperator *LowerNegateToMultiply(Instruction *Neg) { - Constant *Cst = Constant::getAllOnesValue(Neg->getType()); + Type *Ty = Neg->getType(); + Constant *NegOne = Ty->isIntegerTy() ? ConstantInt::getAllOnesValue(Ty) + : ConstantFP::get(Ty, -1.0); - BinaryOperator *Res = - BinaryOperator::CreateMul(Neg->getOperand(1), Cst, "",Neg); - Neg->setOperand(1, Constant::getNullValue(Neg->getType())); // Drop use of op. + BinaryOperator *Res = CreateMul(Neg->getOperand(1), NegOne, "", Neg, Neg); + Neg->setOperand(1, Constant::getNullValue(Ty)); // Drop use of op. Res->takeName(Neg); Neg->replaceAllUsesWith(Res); Res->setDebugLoc(Neg->getDebugLoc()); @@ -377,13 +424,14 @@ static void IncorporateWeight(APInt &LHS, const APInt &RHS, unsigned Opcode) { LHS = 0; // 1 + 1 === 0 modulo 2. return; } - if (Opcode == Instruction::Add) { + if (Opcode == Instruction::Add || Opcode == Instruction::FAdd) { // TODO: Reduce the weight by exploiting nsw/nuw? LHS += RHS; return; } - assert(Opcode == Instruction::Mul && "Unknown associative operation!"); + assert((Opcode == Instruction::Mul || Opcode == Instruction::FMul) && + "Unknown associative operation!"); unsigned Bitwidth = LHS.getBitWidth(); // If CM is the Carmichael number then a weight W satisfying W >= CM+Bitwidth // can be replaced with W-CM. That's because x^W=x^(W-CM) for every Bitwidth @@ -499,8 +547,7 @@ static bool LinearizeExprTree(BinaryOperator *I, DEBUG(dbgs() << "LINEARIZE: " << *I << '\n'); unsigned Bitwidth = I->getType()->getScalarType()->getPrimitiveSizeInBits(); unsigned Opcode = I->getOpcode(); - assert(Instruction::isAssociative(Opcode) && - Instruction::isCommutative(Opcode) && + assert(I->isAssociative() && I->isCommutative() && "Expected an associative and commutative operation!"); // Visit all operands of the expression, keeping track of their weight (the @@ -619,15 +666,16 @@ static bool LinearizeExprTree(BinaryOperator *I, // If this is a multiply expression, turn any internal negations into // multiplies by -1 so they can be reassociated. - BinaryOperator *BO = dyn_cast<BinaryOperator>(Op); - if (Opcode == Instruction::Mul && BO && BinaryOperator::isNeg(BO)) { - DEBUG(dbgs() << "MORPH LEAF: " << *Op << " (" << Weight << ") TO "); - BO = LowerNegateToMultiply(BO); - DEBUG(dbgs() << *BO << 'n'); - Worklist.push_back(std::make_pair(BO, Weight)); - MadeChange = true; - continue; - } + if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op)) + if ((Opcode == Instruction::Mul && BinaryOperator::isNeg(BO)) || + (Opcode == Instruction::FMul && BinaryOperator::isFNeg(BO))) { + DEBUG(dbgs() << "MORPH LEAF: " << *Op << " (" << Weight << ") TO "); + BO = LowerNegateToMultiply(BO); + DEBUG(dbgs() << *BO << '\n'); + Worklist.push_back(std::make_pair(BO, Weight)); + MadeChange = true; + continue; + } // Failed to morph into an expression of the right type. This really is // a leaf. @@ -798,6 +846,8 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, Constant *Undef = UndefValue::get(I->getType()); NewOp = BinaryOperator::Create(Instruction::BinaryOps(Opcode), Undef, Undef, "", I); + if (NewOp->getType()->isFloatingPointTy()) + NewOp->setFastMathFlags(I->getFastMathFlags()); } else { NewOp = NodesToRewrite.pop_back_val(); } @@ -817,7 +867,14 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, // expression tree is dominated by all of Ops. if (ExpressionChanged) do { - ExpressionChanged->clearSubclassOptionalData(); + // Preserve FastMathFlags. + if (isa<FPMathOperator>(I)) { + FastMathFlags Flags = I->getFastMathFlags(); + ExpressionChanged->clearSubclassOptionalData(); + ExpressionChanged->setFastMathFlags(Flags); + } else + ExpressionChanged->clearSubclassOptionalData(); + if (ExpressionChanged == I) break; ExpressionChanged->moveBefore(I); @@ -834,6 +891,8 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, /// version of the value is returned, and BI is left pointing at the instruction /// that should be processed next by the reassociation pass. static Value *NegateValue(Value *V, Instruction *BI) { + if (ConstantFP *C = dyn_cast<ConstantFP>(V)) + return ConstantExpr::getFNeg(C); if (Constant *C = dyn_cast<Constant>(V)) return ConstantExpr::getNeg(C); @@ -846,7 +905,8 @@ static Value *NegateValue(Value *V, Instruction *BI) { // the constants. We assume that instcombine will clean up the mess later if // we introduce tons of unnecessary negation instructions. // - if (BinaryOperator *I = isReassociableOp(V, Instruction::Add)) { + if (BinaryOperator *I = + isReassociableOp(V, Instruction::Add, Instruction::FAdd)) { // Push the negates through the add. I->setOperand(0, NegateValue(I->getOperand(0), BI)); I->setOperand(1, NegateValue(I->getOperand(1), BI)); @@ -864,7 +924,8 @@ static Value *NegateValue(Value *V, Instruction *BI) { // 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 (User *U : V->users()) { - if (!BinaryOperator::isNeg(U)) continue; + if (!BinaryOperator::isNeg(U) && !BinaryOperator::isFNeg(U)) + 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 @@ -894,27 +955,30 @@ static Value *NegateValue(Value *V, Instruction *BI) { // Insert a 'neg' instruction that subtracts the value from zero to get the // negation. - return BinaryOperator::CreateNeg(V, V->getName() + ".neg", BI); + return CreateNeg(V, V->getName() + ".neg", BI, BI); } /// ShouldBreakUpSubtract - Return true if we should break up this subtract of /// X-Y into (X + -Y). static bool ShouldBreakUpSubtract(Instruction *Sub) { // If this is a negation, we can't split it up! - if (BinaryOperator::isNeg(Sub)) + if (BinaryOperator::isNeg(Sub) || BinaryOperator::isFNeg(Sub)) return false; // Don't bother to break this up unless either the LHS is an associable add or // subtract or if this is only used by one. - if (isReassociableOp(Sub->getOperand(0), Instruction::Add) || - isReassociableOp(Sub->getOperand(0), Instruction::Sub)) + Value *V0 = Sub->getOperand(0); + if (isReassociableOp(V0, Instruction::Add, Instruction::FAdd) || + isReassociableOp(V0, Instruction::Sub, Instruction::FSub)) return true; - if (isReassociableOp(Sub->getOperand(1), Instruction::Add) || - isReassociableOp(Sub->getOperand(1), Instruction::Sub)) + Value *V1 = Sub->getOperand(1); + if (isReassociableOp(V1, Instruction::Add, Instruction::FAdd) || + isReassociableOp(V1, Instruction::Sub, Instruction::FSub)) return true; + Value *VB = Sub->user_back(); if (Sub->hasOneUse() && - (isReassociableOp(Sub->user_back(), Instruction::Add) || - isReassociableOp(Sub->user_back(), Instruction::Sub))) + (isReassociableOp(VB, Instruction::Add, Instruction::FAdd) || + isReassociableOp(VB, Instruction::Sub, Instruction::FSub))) return true; return false; @@ -931,8 +995,7 @@ static BinaryOperator *BreakUpSubtract(Instruction *Sub) { // and set it as the RHS of the add instruction we just made. // Value *NegVal = NegateValue(Sub->getOperand(1), Sub); - BinaryOperator *New = - BinaryOperator::CreateAdd(Sub->getOperand(0), NegVal, "", Sub); + BinaryOperator *New = CreateAdd(Sub->getOperand(0), NegVal, "", Sub, Sub); Sub->setOperand(0, Constant::getNullValue(Sub->getType())); // Drop use of op. Sub->setOperand(1, Constant::getNullValue(Sub->getType())); // Drop use of op. New->takeName(Sub); @@ -988,15 +1051,16 @@ static Value *EmitAddTreeOfValues(Instruction *I, Value *V1 = Ops.back(); Ops.pop_back(); Value *V2 = EmitAddTreeOfValues(I, Ops); - return BinaryOperator::CreateAdd(V2, V1, "tmp", I); + return CreateAdd(V2, V1, "tmp", I, I); } /// RemoveFactorFromExpression - If V is an expression tree that is a /// multiplication sequence, and if this sequence contains a multiply by Factor, /// remove Factor from the tree and return the new tree. Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) { - BinaryOperator *BO = isReassociableOp(V, Instruction::Mul); - if (!BO) return nullptr; + BinaryOperator *BO = isReassociableOp(V, Instruction::Mul, Instruction::FMul); + if (!BO) + return nullptr; SmallVector<RepeatedValue, 8> Tree; MadeChange |= LinearizeExprTree(BO, Tree); @@ -1018,13 +1082,25 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) { } // If this is a negative version of this factor, remove it. - if (ConstantInt *FC1 = dyn_cast<ConstantInt>(Factor)) + if (ConstantInt *FC1 = dyn_cast<ConstantInt>(Factor)) { if (ConstantInt *FC2 = dyn_cast<ConstantInt>(Factors[i].Op)) if (FC1->getValue() == -FC2->getValue()) { FoundFactor = NeedsNegate = true; Factors.erase(Factors.begin()+i); break; } + } else if (ConstantFP *FC1 = dyn_cast<ConstantFP>(Factor)) { + if (ConstantFP *FC2 = dyn_cast<ConstantFP>(Factors[i].Op)) { + APFloat F1(FC1->getValueAPF()); + APFloat F2(FC2->getValueAPF()); + F2.changeSign(); + if (F1.compare(F2) == APFloat::cmpEqual) { + FoundFactor = NeedsNegate = true; + Factors.erase(Factors.begin() + i); + break; + } + } + } } if (!FoundFactor) { @@ -1046,7 +1122,7 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) { } if (NeedsNegate) - V = BinaryOperator::CreateNeg(V, "neg", InsertPt); + V = CreateNeg(V, "neg", InsertPt, BO); return V; } @@ -1058,7 +1134,7 @@ Value *Reassociate::RemoveFactorFromExpression(Value *V, Value *Factor) { static void FindSingleUseMultiplyFactors(Value *V, SmallVectorImpl<Value*> &Factors, const SmallVectorImpl<ValueEntry> &Ops) { - BinaryOperator *BO = isReassociableOp(V, Instruction::Mul); + BinaryOperator *BO = isReassociableOp(V, Instruction::Mul, Instruction::FMul); if (!BO) { Factors.push_back(V); return; @@ -1389,13 +1465,15 @@ Value *Reassociate::OptimizeAdd(Instruction *I, ++NumFactor; // Insert a new multiply. - Value *Mul = ConstantInt::get(cast<IntegerType>(I->getType()), NumFound); - Mul = BinaryOperator::CreateMul(TheOp, Mul, "factor", I); + Type *Ty = TheOp->getType(); + Constant *C = Ty->isIntegerTy() ? ConstantInt::get(Ty, NumFound) + : ConstantFP::get(Ty, NumFound); + Instruction *Mul = CreateMul(TheOp, C, "factor", I, I); // Now that we have inserted a multiply, optimize it. This allows us to // handle cases that require multiple factoring steps, such as this: // (X*2) + (X*2) + (X*2) -> (X*2)*3 -> X*6 - RedoInsts.insert(cast<Instruction>(Mul)); + RedoInsts.insert(Mul); // If every add operand was a duplicate, return the multiply. if (Ops.empty()) @@ -1412,11 +1490,12 @@ Value *Reassociate::OptimizeAdd(Instruction *I, } // Check for X and -X or X and ~X in the operand list. - if (!BinaryOperator::isNeg(TheOp) && !BinaryOperator::isNot(TheOp)) + if (!BinaryOperator::isNeg(TheOp) && !BinaryOperator::isFNeg(TheOp) && + !BinaryOperator::isNot(TheOp)) continue; Value *X = nullptr; - if (BinaryOperator::isNeg(TheOp)) + if (BinaryOperator::isNeg(TheOp) || BinaryOperator::isFNeg(TheOp)) X = BinaryOperator::getNegArgument(TheOp); else if (BinaryOperator::isNot(TheOp)) X = BinaryOperator::getNotArgument(TheOp); @@ -1426,7 +1505,8 @@ Value *Reassociate::OptimizeAdd(Instruction *I, continue; // Remove X and -X from the operand list. - if (Ops.size() == 2 && BinaryOperator::isNeg(TheOp)) + if (Ops.size() == 2 && + (BinaryOperator::isNeg(TheOp) || BinaryOperator::isFNeg(TheOp))) return Constant::getNullValue(X->getType()); // Remove X and ~X from the operand list. @@ -1463,7 +1543,8 @@ Value *Reassociate::OptimizeAdd(Instruction *I, unsigned MaxOcc = 0; Value *MaxOccVal = nullptr; for (unsigned i = 0, e = Ops.size(); i != e; ++i) { - BinaryOperator *BOp = isReassociableOp(Ops[i].Op, Instruction::Mul); + BinaryOperator *BOp = + isReassociableOp(Ops[i].Op, Instruction::Mul, Instruction::FMul); if (!BOp) continue; @@ -1476,23 +1557,43 @@ Value *Reassociate::OptimizeAdd(Instruction *I, SmallPtrSet<Value*, 8> Duplicates; for (unsigned i = 0, e = Factors.size(); i != e; ++i) { Value *Factor = Factors[i]; - if (!Duplicates.insert(Factor)) continue; + if (!Duplicates.insert(Factor)) + continue; unsigned Occ = ++FactorOccurrences[Factor]; - if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factor; } + if (Occ > MaxOcc) { + MaxOcc = Occ; + MaxOccVal = Factor; + } // If Factor is a negative constant, add the negated value as a factor // because we can percolate the negate out. Watch for minint, which // cannot be positivified. - if (ConstantInt *CI = dyn_cast<ConstantInt>(Factor)) + if (ConstantInt *CI = dyn_cast<ConstantInt>(Factor)) { if (CI->isNegative() && !CI->isMinValue(true)) { Factor = ConstantInt::get(CI->getContext(), -CI->getValue()); assert(!Duplicates.count(Factor) && "Shouldn't have two constant factors, missed a canonicalize"); - unsigned Occ = ++FactorOccurrences[Factor]; - if (Occ > MaxOcc) { MaxOcc = Occ; MaxOccVal = Factor; } + if (Occ > MaxOcc) { + MaxOcc = Occ; + MaxOccVal = Factor; + } + } + } else if (ConstantFP *CF = dyn_cast<ConstantFP>(Factor)) { + if (CF->isNegative()) { + APFloat F(CF->getValueAPF()); + F.changeSign(); + Factor = ConstantFP::get(CF->getContext(), F); + assert(!Duplicates.count(Factor) && + "Shouldn't have two constant factors, missed a canonicalize"); + unsigned Occ = ++FactorOccurrences[Factor]; + if (Occ > MaxOcc) { + MaxOcc = Occ; + MaxOccVal = Factor; + } } + } } } @@ -1505,11 +1606,16 @@ Value *Reassociate::OptimizeAdd(Instruction *I, // this, we could otherwise run into situations where removing a factor // from an expression will drop a use of maxocc, and this can cause // RemoveFactorFromExpression on successive values to behave differently. - Instruction *DummyInst = BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal); + Instruction *DummyInst = + I->getType()->isIntegerTy() + ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal) + : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal); + SmallVector<WeakVH, 4> NewMulOps; for (unsigned i = 0; i != Ops.size(); ++i) { // Only try to remove factors from expressions we're allowed to. - BinaryOperator *BOp = isReassociableOp(Ops[i].Op, Instruction::Mul); + BinaryOperator *BOp = + isReassociableOp(Ops[i].Op, Instruction::Mul, Instruction::FMul); if (!BOp) continue; @@ -1542,7 +1648,7 @@ Value *Reassociate::OptimizeAdd(Instruction *I, RedoInsts.insert(VI); // Create the multiply. - Instruction *V2 = BinaryOperator::CreateMul(V, MaxOccVal, "tmp", I); + Instruction *V2 = CreateMul(V, MaxOccVal, "tmp", I, I); // Rerun associate on the multiply in case the inner expression turned into // a multiply. We want to make sure that we keep things in canonical form. @@ -1632,7 +1738,10 @@ static Value *buildMultiplyTree(IRBuilder<> &Builder, Value *LHS = Ops.pop_back_val(); do { - LHS = Builder.CreateMul(LHS, Ops.pop_back_val()); + if (LHS->getType()->isIntegerTy()) + LHS = Builder.CreateMul(LHS, Ops.pop_back_val()); + else + LHS = Builder.CreateFMul(LHS, Ops.pop_back_val()); } while (!Ops.empty()); return LHS; @@ -1765,11 +1874,13 @@ Value *Reassociate::OptimizeExpression(BinaryOperator *I, break; case Instruction::Add: + case Instruction::FAdd: if (Value *Result = OptimizeAdd(I, Ops)) return Result; break; case Instruction::Mul: + case Instruction::FMul: if (Value *Result = OptimizeMul(I, Ops)) return Result; break; @@ -1810,8 +1921,7 @@ void Reassociate::OptimizeInst(Instruction *I) { if (!isa<BinaryOperator>(I)) return; - if (I->getOpcode() == Instruction::Shl && - isa<ConstantInt>(I->getOperand(1))) + if (I->getOpcode() == Instruction::Shl && isa<ConstantInt>(I->getOperand(1))) // If an operand of this shift is a reassociable multiply, or if the shift // is used by a reassociable multiply or add, turn into a multiply. if (isReassociableOp(I->getOperand(0), Instruction::Mul) || @@ -1824,28 +1934,33 @@ void Reassociate::OptimizeInst(Instruction *I) { I = NI; } - // Floating point binary operators are not associative, but we can still - // commute (some) of them, to canonicalize the order of their operands. - // This can potentially expose more CSE opportunities, and makes writing - // other transformations simpler. - if ((I->getType()->isFloatingPointTy() || I->getType()->isVectorTy())) { - // FAdd and FMul can be commuted. - if (I->getOpcode() != Instruction::FMul && - I->getOpcode() != Instruction::FAdd) - return; + // Commute floating point binary operators, to canonicalize the order of their + // operands. This can potentially expose more CSE opportunities, and makes + // writing other transformations simpler. + if (I->getType()->isFloatingPointTy() || I->getType()->isVectorTy()) { - Value *LHS = I->getOperand(0); - Value *RHS = I->getOperand(1); - unsigned LHSRank = getRank(LHS); - unsigned RHSRank = getRank(RHS); - - // Sort the operands by rank. - if (RHSRank < LHSRank) { - I->setOperand(0, RHS); - I->setOperand(1, LHS); + // FAdd and FMul can be commuted. + if (I->getOpcode() == Instruction::FMul || + I->getOpcode() == Instruction::FAdd) { + Value *LHS = I->getOperand(0); + Value *RHS = I->getOperand(1); + unsigned LHSRank = getRank(LHS); + unsigned RHSRank = getRank(RHS); + + // Sort the operands by rank. + if (RHSRank < LHSRank) { + I->setOperand(0, RHS); + I->setOperand(1, LHS); + } } - return; + // FIXME: We should commute vector instructions as well. However, this + // requires further analysis to determine the effect on later passes. + + // Don't try to optimize vector instructions or anything that doesn't have + // unsafe algebra. + if (I->getType()->isVectorTy() || !I->hasUnsafeAlgebra()) + return; } // Do not reassociate boolean (i1) expressions. We want to preserve the @@ -1877,6 +1992,24 @@ void Reassociate::OptimizeInst(Instruction *I) { I = NI; } } + } else if (I->getOpcode() == Instruction::FSub) { + if (ShouldBreakUpSubtract(I)) { + Instruction *NI = BreakUpSubtract(I); + RedoInsts.insert(I); + MadeChange = true; + I = NI; + } else if (BinaryOperator::isFNeg(I)) { + // 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(I->getOperand(1), Instruction::FMul) && + (!I->hasOneUse() || + !isReassociableOp(I->user_back(), Instruction::FMul))) { + Instruction *NI = LowerNegateToMultiply(I); + RedoInsts.insert(I); + MadeChange = true; + I = NI; + } + } } // If this instruction is an associative binary operator, process it. @@ -1894,11 +2027,16 @@ void Reassociate::OptimizeInst(Instruction *I) { if (BO->hasOneUse() && BO->getOpcode() == Instruction::Add && cast<Instruction>(BO->user_back())->getOpcode() == Instruction::Sub) return; + if (BO->hasOneUse() && BO->getOpcode() == Instruction::FAdd && + cast<Instruction>(BO->user_back())->getOpcode() == Instruction::FSub) + return; ReassociateExpression(BO); } void Reassociate::ReassociateExpression(BinaryOperator *I) { + assert(!I->getType()->isVectorTy() && + "Reassociation of vector instructions is not supported."); // First, walk the expression tree, linearizing the tree, collecting the // operand information. @@ -1943,12 +2081,21 @@ void Reassociate::ReassociateExpression(BinaryOperator *I) { // this is a multiply tree used only by an add, and the immediate is a -1. // In this case we reassociate to put the negation on the outside so that we // can fold the negation into the add: (-X)*Y + Z -> Z-X*Y - if (I->getOpcode() == Instruction::Mul && I->hasOneUse() && - cast<Instruction>(I->user_back())->getOpcode() == Instruction::Add && - isa<ConstantInt>(Ops.back().Op) && - cast<ConstantInt>(Ops.back().Op)->isAllOnesValue()) { - ValueEntry Tmp = Ops.pop_back_val(); - Ops.insert(Ops.begin(), Tmp); + if (I->hasOneUse()) { + if (I->getOpcode() == Instruction::Mul && + cast<Instruction>(I->user_back())->getOpcode() == Instruction::Add && + isa<ConstantInt>(Ops.back().Op) && + cast<ConstantInt>(Ops.back().Op)->isAllOnesValue()) { + ValueEntry Tmp = Ops.pop_back_val(); + Ops.insert(Ops.begin(), Tmp); + } else if (I->getOpcode() == Instruction::FMul && + cast<Instruction>(I->user_back())->getOpcode() == + Instruction::FAdd && + isa<ConstantFP>(Ops.back().Op) && + cast<ConstantFP>(Ops.back().Op)->isExactlyValue(-1.0)) { + ValueEntry Tmp = Ops.pop_back_val(); + Ops.insert(Ops.begin(), Tmp); + } } DEBUG(dbgs() << "RAOut:\t"; PrintOps(I, Ops); dbgs() << '\n'); |

