Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -167,6 +167,11 @@ cl::desc("Max coefficients in AddRec during evolving"), cl::init(16)); +static cl::opt + HugeExprThreshold("scalar-evolution-huge-expr-threshold", cl::Hidden, + cl::desc("Size of the expression which is considered huge"), + cl::init(4096)); + //===----------------------------------------------------------------------===// // SCEV class definitions //===----------------------------------------------------------------------===// @@ -805,6 +810,14 @@ return F.Size; } +static bool isHugeExpression(const SCEV *S) { + return S->getExpressionSize() >= HugeExprThreshold; +} + +static bool hasHugeExpression(SmallVectorImpl &Ops) { + return std::any_of(Ops.begin(), Ops.end(), isHugeExpression); +} + namespace { struct SCEVDivision : public SCEVVisitor { @@ -2278,7 +2291,7 @@ } // Limit recursion calls depth. - if (Depth > MaxArithDepth) + if (Depth > MaxArithDepth || hasHugeExpression(Ops)) return getOrCreateAddExpr(Ops, Flags); // Okay, check to see if the same value occurs in the operand list more than @@ -2720,7 +2733,7 @@ Flags = StrengthenNoWrapFlags(this, scMulExpr, Ops, Flags); // Limit recursion calls depth. - if (Depth > MaxArithDepth) + if (Depth > MaxArithDepth || hasHugeExpression(Ops)) return getOrCreateMulExpr(Ops, Flags); // If there are any constants, fold them together. @@ -2894,7 +2907,8 @@ // Limit max number of arguments to avoid creation of unreasonably big // SCEVAddRecs with very complex operands. if (AddRec->getNumOperands() + OtherAddRec->getNumOperands() - 1 > - MaxAddRecSize) + MaxAddRecSize || isHugeExpression(AddRec) || + isHugeExpression(OtherAddRec)) continue; bool Overflow = false;