diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h --- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -271,6 +271,10 @@ SkipCurrentLoop = true; } +#ifndef NDEBUG + void setParentLoop(Loop *L) { ParentL = L; } +#endif + /// Loop passes should use this method to indicate they have added new child /// loops of the current loop. /// diff --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp --- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp +++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp @@ -114,6 +114,13 @@ // Check if the current pass preserved the loop-nest object or not. IsLoopNestPtrValid &= PassPA->getChecker().preserved(); +#ifndef NDEBUG + // After running the loop pass, the parent loop might change and we need to + // notify the updater, otherwise U.ParentL might gets outdated and triggers + // assertion failures in addSiblingLoops and addChildLoops. + U.setParentLoop(L.getParentLoop()); +#endif + // FIXME: Historically, the pass managers all called the LLVM context's // yield function here. We don't have a generic way to acquire the // context and it isn't yet clear what the right pattern is for yielding @@ -158,6 +165,13 @@ // aggregate preserved set for this pass manager. PA.intersect(std::move(*PassPA)); +#ifndef NDEBUG + // After running the loop pass, the parent loop might change and we need to + // notify the updater, otherwise U.ParentL might gets outdated and triggers + // assertion failures in addSiblingLoops and addChildLoops. + U.setParentLoop(L.getParentLoop()); +#endif + // FIXME: Historically, the pass managers all called the LLVM context's // yield function here. We don't have a generic way to acquire the // context and it isn't yet clear what the right pattern is for yielding