Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -4086,13 +4086,22 @@ 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) { + static const SCEV *rewrite(const SCEV *S, const Loop *L, ScalarEvolution &SE, + bool IgnoreOtherLoops = false) { SCEVInitRewriter Rewriter(L, SE); const SCEV *Result = Rewriter.visit(S); - return Rewriter.isValid() ? Result : SE.getCouldNotCompute(); + if (!Rewriter.isValid()) + return SE.getCouldNotCompute(); + return Rewriter.isSeenOtherLoops() && !IgnoreOtherLoops + ? SE.getCouldNotCompute() + : Result; } const SCEV *visitUnknown(const SCEVUnknown *Expr) { @@ -4102,21 +4111,24 @@ } const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) { - // Only allow AddRecExprs for this loop. + // Only re-write AddRecExprs for this loop. if (Expr->getLoop() == L) return Expr->getStart(); - Valid = false; + SeenOtherLoops = true; return Expr; } bool isValid() { return Valid; } + bool isSeenOtherLoops() { return SeenOtherLoops; } + private: explicit SCEVInitRewriter(const Loop *L, ScalarEvolution &SE) : SCEVRewriteVisitor(SE), L(L) {} const Loop *L; bool Valid = true; + bool SeenOtherLoops = false; }; /// This class evaluates the compare condition by matching it against the