Index: llvm/lib/Transforms/Scalar/LoopInterchange.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -328,8 +328,8 @@ class LoopInterchangeLegality { public: LoopInterchangeLegality(Loop *Outer, Loop *Inner, ScalarEvolution *SE, - OptimizationRemarkEmitter *ORE) - : OuterLoop(Outer), InnerLoop(Inner), SE(SE), ORE(ORE) {} + DominatorTree *DT, OptimizationRemarkEmitter *ORE) + : OuterLoop(Outer), InnerLoop(Inner), SE(SE), DT(DT), ORE(ORE) {} /// Check if the loops can be interchanged. bool canInterchangeLoops(unsigned InnerLoopId, unsigned OuterLoopId, @@ -347,6 +347,7 @@ private: bool tightlyNested(Loop *Outer, Loop *Inner); + bool hasConditionalStatements(Loop *L); bool containsUnsafeInstructions(BasicBlock *BB); /// Discover induction and reduction PHIs in the header of \p L. Induction @@ -361,6 +362,7 @@ Loop *InnerLoop; ScalarEvolution *SE; + DominatorTree *DT; /// Interface to emit optimization remarks. OptimizationRemarkEmitter *ORE; @@ -542,7 +544,7 @@ Loop *InnerLoop = LoopList[InnerLoopId]; Loop *OuterLoop = LoopList[OuterLoopId]; - LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, ORE); + LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, DT, ORE); if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) { LLVM_DEBUG(dbgs() << "Not interchanging loops. Cannot prove legality.\n"); return false; @@ -679,6 +681,21 @@ return nullptr; } +/// Return true if the Loop has conditional statements. +bool LoopInterchangeLegality::hasConditionalStatements(Loop *L) { + SmallVector ExitingBlocks; + L->getExitingBlocks(ExitingBlocks); + + for (auto BB : L->blocks()) { + for (BasicBlock *ExitingBlock : ExitingBlocks) { + if (!DT->dominates(BB, ExitingBlock)) { + return true; + } + } + } + return false; +} + bool LoopInterchangeLegality::findInductionAndReductions( Loop *L, SmallVector &Inductions, Loop *InnerLoop) { if (!L->getLoopLatch() || !L->getLoopPredecessor()) @@ -760,6 +777,19 @@ return true; } + if (hasConditionalStatements(InnerLoop)) { + LLVM_DEBUG(dbgs() << "Loops including conditional statements cannot be" + << " interchanged.\n "); + ORE->emit([&]() { + return OptimizationRemarkMissed( + DEBUG_TYPE, "UnsupportedConditionalStatements", + InnerLoop->getStartLoc(), InnerLoop->getHeader()) + << "Loops including conditional statements cannot be " + "interchanged."; + }); + return true; + } + // TODO: Currently we handle only loops with 1 induction variable. if (Inductions.size() != 1) { LLVM_DEBUG(dbgs() << "Loops with more than 1 induction variables are not " Index: llvm/test/Transforms/LoopInterchange/lcssa.ll =================================================================== --- llvm/test/Transforms/LoopInterchange/lcssa.ll +++ llvm/test/Transforms/LoopInterchange/lcssa.ll @@ -176,7 +176,7 @@ } ; PHI node in inner latch with multiple predecessors. -; REMARK: Interchanged +; REMARK: UnsupportedConditionalStatements ; REMARK-NEXT: lcssa_05 define void @lcssa_05(i32* %ptr) {