Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -2207,6 +2207,28 @@ return r; } +/// Determine if any of the operands in this SCEV are a constant or if +/// any of the add or multiply expressions in this SCEV contain a constant. +static bool ContainsConstantSomewhere(const SCEV* Expr) { + if (isa(Expr)) + return true; + + const SCEVNAryExpr * Target = dyn_cast(Expr); + if (!Target) + return false; + + for (auto Operand = Target->op_begin(), + E = Target->op_end(); Operand != E; ++Operand) + if ((isa(*Operand)) || (isa(*Operand))) { + if (ContainsConstantSomewhere(*Operand)) + return true; + } else if (isa(*Operand)) { + return true; + } + + return false; +} + /// getMulExpr - Get a canonical multiply expression, or something simpler if /// possible. const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, @@ -2246,11 +2268,13 @@ // C1*(C2+V) -> C1*C2 + C1*V if (Ops.size() == 2) - if (const SCEVAddExpr *Add = dyn_cast(Ops[1])) - if (Add->getNumOperands() == 2 && - isa(Add->getOperand(0))) - return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)), - getMulExpr(LHSC, Add->getOperand(1))); + if (const SCEVAddExpr *Add = dyn_cast(Ops[1])) + // if any of Add's ops are Adds or Muls with a constant + // then apply this transformation as well + if (Add->getNumOperands() == 2) + if (ContainsConstantSomewhere(Add)) + return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)), + getMulExpr(LHSC, Add->getOperand(1))); ++Idx; while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) {