diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 57a091d7d7f920..a33621170c02fd 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -745,11 +745,8 @@ class ScalarEvolution { 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 index 3acaecde13515e..872c515fd9090e 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6970,11 +6970,17 @@ unsigned ScalarEvolution::getSmallConstantMaxTripCount(const Loop *L) { } 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 index f57ab3dbdad365..34a07aa70a48c2 100644 --- a/llvm/test/Analysis/ScalarEvolution/tripmultiple_calculation.ll +++ b/llvm/test/Analysis/ScalarEvolution/tripmultiple_calculation.ll @@ -124,3 +124,27 @@ exit: 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 +} +