diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -745,11 +745,8 @@ const SCEV *ExitCount); /// Returns the largest constant divisor of the trip count of the - /// loop if it is a single-exit loop and we can compute a small maximum for - /// that loop. - /// - /// Implemented in terms of the \c getSmallConstantTripMultiple overload with - /// the single exiting block passed to it. See that routine for details. + /// loop. Will return 1 if no trip count could be computed, or if a + /// divisor could not be found. unsigned getSmallConstantTripMultiple(const Loop *L); /// Returns the largest constant divisor of the trip count of this loop as a diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6970,11 +6970,17 @@ } unsigned ScalarEvolution::getSmallConstantTripMultiple(const Loop *L) { - if (BasicBlock *ExitingBB = L->getExitingBlock()) - return getSmallConstantTripMultiple(L, ExitingBB); + SmallVector ExitingBlocks; + L->getExitingBlocks(ExitingBlocks); - // No trip multiple information for multiple exits. - return 0; + Optional Res = None; + for (auto *ExitingBB : ExitingBlocks) { + unsigned Multiple = getSmallConstantTripMultiple(L, ExitingBB); + if (!Res) + Res = Multiple; + Res = (unsigned)GreatestCommonDivisor64(*Res, Multiple); + } + return Res.getValueOr(1); } unsigned ScalarEvolution::getSmallConstantTripMultiple(const Loop *L, diff --git a/llvm/test/Analysis/ScalarEvolution/tripmultiple_calculation.ll b/llvm/test/Analysis/ScalarEvolution/tripmultiple_calculation.ll --- a/llvm/test/Analysis/ScalarEvolution/tripmultiple_calculation.ll +++ b/llvm/test/Analysis/ScalarEvolution/tripmultiple_calculation.ll @@ -124,3 +124,27 @@ ret i32 0 } +; If there are multiple exits, the result is the GCD of the multiples +; of each individual exit (since we don't know which is taken). + +; CHECK: Loop %l4: Trip multiple is 50 + +define i32 @foo5(i32 %n) { +entry: + br label %l4 + +l4: + %x.0 = phi i32 [ 0, %entry ], [ %inc, %l4-latch ] + call void @f() + %inc = add i32 %x.0, 1 + %earlycond = icmp eq i32 %inc, 150 + br i1 %earlycond, label %exit, label %l4-latch + +l4-latch: + %exitcond = icmp eq i32 %inc, 200 + br i1 %exitcond, label %exit, label %l4 + +exit: + ret i32 0 +} +