diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index e4ed367a6962ea..92f9949188a1d7 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -2700,8 +2700,32 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, // If there are any constants, fold them together. unsigned Idx = 0; if (const SCEVConstant *LHSC = dyn_cast(Ops[0])) { + ++Idx; + assert(Idx < Ops.size()); + while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { + // We found two constants, fold them together! + Ops[0] = getConstant(LHSC->getAPInt() * RHSC->getAPInt()); + if (Ops.size() == 2) return Ops[0]; + Ops.erase(Ops.begin()+1); // Erase the folded element + LHSC = cast(Ops[0]); + } + + // If we have a multiply of zero, it will always be zero. + if (LHSC->getValue()->isZero()) + return LHSC; + + // If we are left with a constant one being multiplied, strip it off. + if (LHSC->getValue()->isOne()) { + Ops.erase(Ops.begin()); + --Idx; + } + + if (Ops.size() == 1) + return Ops[0]; + } - if (Ops.size() == 2) + if (const SCEVConstant *LHSC = dyn_cast(Ops[0])) { + if (Ops.size() == 2) { // C1*(C2+V) -> C1*C2 + C1*V if (const SCEVAddExpr *Add = dyn_cast(Ops[1])) // If any of Add's ops are Adds or Muls with a constant, apply this @@ -2717,28 +2741,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, SCEV::FlagAnyWrap, Depth + 1), SCEV::FlagAnyWrap, Depth + 1); - ++Idx; - while (const SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { - // We found two constants, fold them together! - ConstantInt *Fold = - ConstantInt::get(getContext(), LHSC->getAPInt() * RHSC->getAPInt()); - Ops[0] = getConstant(Fold); - Ops.erase(Ops.begin()+1); // Erase the folded element - if (Ops.size() == 1) return Ops[0]; - LHSC = cast(Ops[0]); - } - - // If we are left with a constant one being multiplied, strip it off. - if (cast(Ops[0])->getValue()->isOne()) { - Ops.erase(Ops.begin()); - --Idx; - } else if (cast(Ops[0])->getValue()->isZero()) { - // If we have a multiply of zero, it will always be zero. - return Ops[0]; - } else if (Ops[0]->isAllOnesValue()) { - // If we have a mul by -1 of an add, try distributing the -1 among the - // add operands. - if (Ops.size() == 2) { + if (Ops[0]->isAllOnesValue()) { + // If we have a mul by -1 of an add, try distributing the -1 among the + // add operands. if (const SCEVAddExpr *Add = dyn_cast(Ops[1])) { SmallVector NewOps; bool AnyFolded = false; @@ -2762,9 +2767,6 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, } } } - - if (Ops.size() == 1) - return Ops[0]; } // Skip over the add expression until we get to a multiply.