Index: llvm/include/llvm/Transforms/Scalar/LoopPassManager.h =================================================================== --- llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -356,6 +356,14 @@ Worklist.insert(CurrentL); } + bool isLoopNestChanged() const { + return LoopNestChanged; + } + + void markLoopNestChanged(bool Changed) { + LoopNestChanged = Changed; + } + private: friend class llvm::FunctionToLoopPassAdaptor; @@ -368,6 +376,7 @@ Loop *CurrentL; bool SkipCurrentLoop; const bool LoopNestMode; + bool LoopNestChanged; #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS // In debug builds we also track the parent loop to implement asserts even in @@ -376,8 +385,10 @@ #endif LPMUpdater(SmallPriorityWorklist &Worklist, - LoopAnalysisManager &LAM, bool LoopNestMode = false) - : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode) {} + LoopAnalysisManager &LAM, bool LoopNestMode = false, + bool LoopNestChanged = false) + : Worklist(Worklist), LAM(LAM), LoopNestMode(LoopNestMode), + LoopNestChanged(LoopNestChanged) {} }; template Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -44,6 +44,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include @@ -1766,5 +1767,6 @@ OptimizationRemarkEmitter ORE(&F); if (!LoopInterchange(&AR.SE, &AR.LI, &DI, &AR.DT, CC, &ORE).run(LN)) return PreservedAnalyses::all(); + U.markLoopNestChanged(true); return getLoopPassPreservedAnalyses(); } Index: llvm/lib/Transforms/Scalar/LoopPassManager.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopPassManager.cpp +++ llvm/lib/Transforms/Scalar/LoopPassManager.cpp @@ -78,6 +78,8 @@ unsigned LoopPassIndex = 0, LoopNestPassIndex = 0; + Loop *OuterMostLoop = &L; + for (size_t I = 0, E = IsLoopNestPass.size(); I != E; ++I) { Optional PassPA; if (!IsLoopNestPass[I]) { @@ -87,9 +89,17 @@ } else { // The `I`-th pass is a loop-nest pass. auto &Pass = LoopNestPasses[LoopNestPassIndex++]; - - LoopNest &LN = AM.getResult(L, AR); + assert(OuterMostLoop->isOutermost() && + "LoopNest should be constructed only with the outermost loop!"); + LoopNest &LN = AM.getResult(*OuterMostLoop, AR); PassPA = runSinglePass(LN, Pass, AM, AR, U, PI); + + // Restore the correct loopnest status. + if (U.isLoopNestChanged()) { + while (auto *PL = OuterMostLoop->getParentLoop()) + OuterMostLoop = PL; + U.markLoopNestChanged(false); + } } // `PassPA` is `None` means that the before-pass callbacks in