Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -6890,63 +6890,12 @@ ScalarEvolution::ExitLimit ScalarEvolution::computeExitLimit(const Loop *L, BasicBlock *ExitingBlock, bool AllowPredicates) { - // Okay, we've chosen an exiting block. See what condition causes us to exit - // at this block and remember the exit block and whether all other targets - // lead to the loop header. - bool MustExecuteLoopHeader = true; - BasicBlock *Exit = nullptr; - for (auto *SBB : successors(ExitingBlock)) - if (!L->contains(SBB)) { - if (Exit) // Multiple exit successors. - return getCouldNotCompute(); - Exit = SBB; - } else if (SBB != L->getHeader()) { - MustExecuteLoopHeader = false; - } - - // At this point, we know we have a conditional branch that determines whether - // the loop is exited. However, we don't know if the branch is executed each - // time through the loop. If not, then the execution count of the branch will - // not be equal to the trip count of the loop. - // - // Currently we check for this by checking to see if the Exit branch goes to - // the loop header. If so, we know it will always execute the same number of - // times as the loop. We also handle the case where the exit block *is* the - // loop header. This is common for un-rotated loops. - // - // If both of those tests fail, walk up the unique predecessor chain to the - // header, stopping if there is an edge that doesn't exit the loop. If the - // header is reached, the execution count of the branch will be equal to the - // trip count of the loop. - // - // More extensive analysis could be done to handle more cases here. - // - if (!MustExecuteLoopHeader && ExitingBlock != L->getHeader()) { - // The simple checks failed, try climbing the unique predecessor chain - // up to the header. - bool Ok = false; - for (BasicBlock *BB = ExitingBlock; BB; ) { - BasicBlock *Pred = BB->getUniquePredecessor(); - if (!Pred) - return getCouldNotCompute(); - TerminatorInst *PredTerm = Pred->getTerminator(); - for (const BasicBlock *PredSucc : PredTerm->successors()) { - if (PredSucc == BB) - continue; - // If the predecessor has a successor that isn't BB and isn't - // outside the loop, assume the worst. - if (L->contains(PredSucc)) - return getCouldNotCompute(); - } - if (Pred == L->getHeader()) { - Ok = true; - break; - } - BB = Pred; - } - if (!Ok) - return getCouldNotCompute(); - } + assert(L->contains(ExitingBlock) && "Exit count for non-loop block?"); + // If our exiting block does not dominate the latch, then its connection with + // loop's exit limit may be far from trivial. + const BasicBlock *Latch = L->getLoopLatch(); + if (!Latch || !DT.dominates(ExitingBlock, Latch)) + return getCouldNotCompute(); bool IsOnlyExit = (L->getExitingBlock() != nullptr); TerminatorInst *Term = ExitingBlock->getTerminator(); @@ -6961,9 +6910,19 @@ /*ControlsExit=*/IsOnlyExit, AllowPredicates); } - if (SwitchInst *SI = dyn_cast(Term)) + if (SwitchInst *SI = dyn_cast(Term)) { + // For switch, make sure that there is a single exit from the loop. + BasicBlock *Exit = nullptr; + for (auto *SBB : successors(ExitingBlock)) + if (!L->contains(SBB)) { + if (Exit) // Multiple exit successors. + return getCouldNotCompute(); + Exit = SBB; + } + return computeExitLimitFromSingleExitSwitch(L, SI, Exit, /*ControlsExit=*/IsOnlyExit); + } return getCouldNotCompute(); } Index: test/Analysis/ScalarEvolution/exact_iter_count.ll =================================================================== --- test/Analysis/ScalarEvolution/exact_iter_count.ll +++ test/Analysis/ScalarEvolution/exact_iter_count.ll @@ -25,3 +25,37 @@ side.exit: ret void } + +define void @test_02(i1 %c) { + +; CHECK-LABEL: Determining loop execution counts for: @test_02 +; CHECK-NEXT: Loop %loop: backedge-taken count is 50 + +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] + br i1 %c, label %if.true, label %if.false + +if.true: + br label %merge + +if.false: + br label %merge + +merge: + %side.cond = icmp slt i32 %iv, 50 + br i1 %side.cond, label %backedge, label %side.exit + +backedge: + %iv.next = add i32 %iv, 1 + %loop.cond = icmp slt i32 %iv, 100 + br i1 %loop.cond, label %loop, label %exit + +exit: + ret void + +side.exit: + ret void +}