diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/DependenceAnalysis.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopNestAnalysis.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ScalarEvolution.h" @@ -617,6 +618,22 @@ containsUnsafeInstructions(InnerLoopPreHeader)) return false; + BasicBlock *InnerLoopExit = InnerLoop->getExitBlock(); + // Ensure the inner loop exit block flow to the outer loop latch possibly + // through empty blocks + const BasicBlock &SuccInner = + LoopNest::skipEmptyBlockUntil(InnerLoopExit, OuterLoopLatch); + if (&SuccInner != OuterLoopLatch) { + LLVM_DEBUG(dbgs() << "Inner loop exit block " << *InnerLoopExit + << " does not lead to the outer loop latch.\n";); + return false; + } + // The inner loop exit block does flow to the outer loop latch and not some + // other BBs, now make sure it contains safe instructions, since it will be + // move into the (new) inner loop after interchange + if (containsUnsafeInstructions(InnerLoopExit)) + return false; + LLVM_DEBUG(dbgs() << "Loops are perfectly nested\n"); // We have a perfect loop nest. return true; diff --git a/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll b/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll --- a/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll +++ b/llvm/test/Transforms/LoopInterchange/not-interchanged-tightly-nested.ll @@ -9,6 +9,7 @@ @B = common global [100 x i32] zeroinitializer @C = common global [100 x [100 x i32]] zeroinitializer @D = common global [100 x [100 x [100 x i32]]] zeroinitializer +@E = common global [100 x [100 x i64]] zeroinitializer ;; Loops not tightly nested are not interchanged ;; for(int j=0;j