Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -347,6 +347,7 @@ private: bool tightlyNested(Loop *Outer, Loop *Inner); + bool containsUnsafeInstructionsInInnerLoop(void); bool containsUnsafeInstructions(BasicBlock *BB); /// Discover induction and reduction PHIs in the header of \p L. Induction @@ -578,6 +579,33 @@ } // end anonymous namespace +/// Returns true if there are unsafe instructions above or below +/// the inner loop. +bool LoopInterchangeLegality::containsUnsafeInstructionsInInnerLoop() { + BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader(); + BasicBlock *InnerLoopExit = InnerLoop->getExitBlock(); + BasicBlock *OuterLoopHeader = OuterLoop->getHeader(); + BasicBlock *OuterLoopLatch = OuterLoop->getLoopLatch(); + + // Check loop preheader. + if (InnerLoopPreHeader != OuterLoopHeader) { + for (Instruction &I : *InnerLoopPreHeader) { + if (!isa(&I) && !isa(&I)) + return true; + } + } + // Check loop latch + if (InnerLoopExit != OuterLoopLatch) { + for (Instruction &I : *InnerLoopExit) { + if (!isa(&I) && !isa(&I) && + !isa(&I)) + return true; + } + } + + return false; +} + bool LoopInterchangeLegality::containsUnsafeInstructions(BasicBlock *BB) { return any_of(*BB, [](const Instruction &I) { return I.mayHaveSideEffects() || I.mayReadFromMemory(); @@ -618,6 +646,9 @@ containsUnsafeInstructions(InnerLoopPreHeader)) return false; + if (containsUnsafeInstructionsInInnerLoop()) + return false; + LLVM_DEBUG(dbgs() << "Loops are perfectly nested\n"); // We have a perfect loop nest. return true;