Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -4086,11 +4086,16 @@ namespace { +/// Takes SCEV S and Loop L. For each AddRec sub-expression, use its start +/// expression in case its Loop is L. If it is not L then +/// if IgnoreOtherLoops is true then use AddRec itself +/// otherwise rewrite cannot be done. +/// If SCEV contains non-invariant unknown SCEV rewrite cannot be done. class SCEVInitRewriter : public SCEVRewriteVisitor { public: - static const SCEV *rewrite(const SCEV *S, const Loop *L, - ScalarEvolution &SE) { - SCEVInitRewriter Rewriter(L, SE); + static const SCEV *rewrite(const SCEV *S, const Loop *L, ScalarEvolution &SE, + bool IgnoreOtherLoops = false) { + SCEVInitRewriter Rewriter(L, SE, IgnoreOtherLoops); const SCEV *Result = Rewriter.visit(S); return Rewriter.isValid() ? Result : SE.getCouldNotCompute(); } @@ -4105,17 +4110,20 @@ // Only allow AddRecExprs for this loop. if (Expr->getLoop() == L) return Expr->getStart(); - Valid = false; + // If we should not ignore other loops then invalidate result. + Valid = Valid && IgnoreOtherLoops; return Expr; } bool isValid() { return Valid; } private: - explicit SCEVInitRewriter(const Loop *L, ScalarEvolution &SE) - : SCEVRewriteVisitor(SE), L(L) {} + explicit SCEVInitRewriter(const Loop *L, ScalarEvolution &SE, + bool IgnoreOtherLoops) + : SCEVRewriteVisitor(SE), L(L), IgnoreOtherLoops(IgnoreOtherLoops) {} const Loop *L; + const bool IgnoreOtherLoops; bool Valid = true; };