diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1781,26 +1781,6 @@ return false; } - // We must have a single exiting block. - if (!TheLoop->getExitingBlock()) { - LLVM_DEBUG( - dbgs() << "LAA: loop control flow is not understood by analyzer\n"); - recordAnalysis("CFGNotUnderstood") - << "loop control flow is not understood by analyzer"; - return false; - } - - // We only handle bottom-tested loops, i.e. loop in which the condition is - // checked at the end of each iteration. With that we can assume that all - // instructions in the loop are executed the same number of times. - if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) { - LLVM_DEBUG( - dbgs() << "LAA: loop control flow is not understood by analyzer\n"); - recordAnalysis("CFGNotUnderstood") - << "loop control flow is not understood by analyzer"; - return false; - } - // ScalarEvolution needs to be able to find the exit count. const SCEV *ExitCount = PSE->getBackedgeTakenCount(); if (isa(ExitCount)) { diff --git a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp --- a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp +++ b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp @@ -670,15 +670,17 @@ << L->getHeader()->getParent()->getName() << "\" checking " << *L << "\n"); + // Having a single exit block implies there's also one exiting block. if (!L->getExitBlock()) return fail("MultipleExitBlocks", "multiple exit blocks"); if (!L->isLoopSimplifyForm()) return fail("NotLoopSimplifyForm", "loop is not in loop-simplify form"); + if (!L->isRotatedForm()) + return fail("NotBottomTested", "loop is not bottom tested"); BasicBlock *PH = L->getLoopPreheader(); - // LAA will check that we only have a single exiting block. LAI = &GetLAA(*L); // Currently, we only distribute to isolate the part of the loop with diff --git a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp --- a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp +++ b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp @@ -632,6 +632,9 @@ // Now walk the identified inner loops. for (Loop *L : Worklist) { + // Match historical behavior + if (!L->isRotatedForm() || !L->getExitingBlock()) + continue; // The actual work is performed by LoadEliminationForLoop. LoadEliminationForLoop LEL(L, &LI, GetLAI(*L), &DT, BFI, PSI); Changed |= LEL.processLoop(); diff --git a/llvm/lib/Transforms/Utils/LoopVersioning.cpp b/llvm/lib/Transforms/Utils/LoopVersioning.cpp --- a/llvm/lib/Transforms/Utils/LoopVersioning.cpp +++ b/llvm/lib/Transforms/Utils/LoopVersioning.cpp @@ -269,8 +269,11 @@ // Now walk the identified inner loops. bool Changed = false; for (Loop *L : Worklist) { + if (!L->isLoopSimplifyForm() || !L->isRotatedForm() || + !L->getExitingBlock()) + continue; const LoopAccessInfo &LAI = GetLAA(*L); - if (L->isLoopSimplifyForm() && !LAI.hasConvergentOp() && + if (!LAI.hasConvergentOp() && (LAI.getNumRuntimePointerChecks() || !LAI.getPSE().getUnionPredicate().isAlwaysTrue())) { LoopVersioning LVer(LAI, LAI.getRuntimePointerChecking()->getChecks(), L,