[llvm] r328611 - [SCEV] Make exact taken count calculation more optimistic

Mikael Holmén via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 30 01:38:40 PDT 2018


Hi Max,

I found a case where this commit makes opt hit an assertion:

opt -indvars -loop-unswitch -S -o - foo.ll

gives

opt: ../lib/Analysis/ScalarEvolution.cpp:6726: const llvm::SCEV 
*llvm::ScalarEvolution::BackedgeTakenInfo::getExact(const llvm::Loop *, 
llvm::ScalarEvolution *, llvm::SCEVUnionPredicate *) const: Assertion 
`SE->DT.dominates(ENT.ExitingBlock, Latch) && "We should only have known 
counts for exiting blocks that dominate " "latch!"' failed.
Stack dump:
0.      Program arguments: /data/repo/llvm-patch/build-all/bin/opt 
-indvars -loop-unswitch -S -o - foo.ll
1.      Running pass 'Function Pass Manager' on module 'foo.ll'.
2.      Running pass 'Loop Pass Manager' on function '@func_46'
3.      Running pass 'Induction Variable Simplification' on basic block 
'%for.body2688.preheader'
#0 0x0000000001f59554 PrintStackTraceSignalHandler(void*) 
(/data/repo/llvm-patch/build-all/bin/opt+0x1f59554)
#1 0x0000000001f59cc6 SignalHandler(int) 
(/data/repo/llvm-patch/build-all/bin/opt+0x1f59cc6)
#2 0x00007f16bdc39330 __restore_rt 
(/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)
#3 0x00007f16bc828c37 gsignal 
/build/eglibc-ripdx6/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0
#4 0x00007f16bc82c028 abort 
/build/eglibc-ripdx6/eglibc-2.19/stdlib/abort.c:91:0
#5 0x00007f16bc821bf6 __assert_fail_base 
/build/eglibc-ripdx6/eglibc-2.19/assert/assert.c:92:0
#6 0x00007f16bc821ca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)
#7 0x000000000153fa56 
llvm::ScalarEvolution::BackedgeTakenInfo::getExact(llvm::Loop const*, 
llvm::ScalarEvolution*, llvm::SCEVUnionPredicate*) const 
(/data/repo/llvm-patch/build-all/bin/opt+0x153fa56)
#8 0x0000000001d57cca (anonymous 
namespace)::IndVarSimplify::run(llvm::Loop*) 
(/data/repo/llvm-patch/build-all/bin/opt+0x1d57cca)
#9 0x0000000001d5d1cc (anonymous 
namespace)::IndVarSimplifyLegacyPass::runOnLoop(llvm::Loop*, 
llvm::LPPassManager&) (/data/repo/llvm-patch/build-all/bin/opt+0x1d5d1cc)
#10 0x00000000014c878d 
llvm::LPPassManager::runOnFunction(llvm::Function&) 
(/data/repo/llvm-patch/build-all/bin/opt+0x14c878d)
#11 0x00000000019ff8b8 
llvm::FPPassManager::runOnFunction(llvm::Function&) 
(/data/repo/llvm-patch/build-all/bin/opt+0x19ff8b8)
#12 0x00000000019ffaf8 llvm::FPPassManager::runOnModule(llvm::Module&) 
(/data/repo/llvm-patch/build-all/bin/opt+0x19ffaf8)
#13 0x00000000019fffd5 llvm::legacy::PassManagerImpl::run(llvm::Module&) 
(/data/repo/llvm-patch/build-all/bin/opt+0x19fffd5)
#14 0x0000000000737e55 main 
(/data/repo/llvm-patch/build-all/bin/opt+0x737e55)
#15 0x00007f16bc813f45 __libc_start_main 
/build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0
#16 0x000000000072191d _start 
(/data/repo/llvm-patch/build-all/bin/opt+0x72191d)

Regards,
Mikael


On 03/27/2018 09:30 AM, Max Kazantsev via llvm-commits wrote:
> Author: mkazantsev
> Date: Tue Mar 27 00:30:38 2018
> New Revision: 328611
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=328611&view=rev
> Log:
> [SCEV] Make exact taken count calculation more optimistic
> 
> Currently, `getExact` fails if it sees two exit counts in different blocks. There is
> no solid reason to do so, given that we only calculate exact non-taken count
> for exiting blocks that dominate latch. Using this fact, we can simply take min
> out of all exits of all blocks to get the exact taken count.
> 
> This patch makes the calculation more optimistic with enforcing our assumption
> with asserts. It allows us to calculate exact backedge taken count in trivial loops
> like
> 
>    for (int i = 0; i < 100; i++) {
>      if (i > 50) break;
>      . . .
>    }
> 
> Differential Revision: https://reviews.llvm.org/D44676
> Reviewed By: fhahn
> 
> Added:
>      llvm/trunk/test/Analysis/ScalarEvolution/exact_iter_count.ll
> Modified:
>      llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
>      llvm/trunk/lib/Analysis/ScalarEvolution.cpp
>      llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll
>      llvm/trunk/test/Analysis/ScalarEvolution/trip-count14.ll
>      llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate10.ll
>      llvm/trunk/test/Transforms/LoopSimplify/preserve-scev.ll
> 
> Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=328611&r1=328610&r2=328611&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
> +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Tue Mar 27 00:30:38 2018
> @@ -1288,7 +1288,7 @@ private:
>       /// If we allowed SCEV predicates to be generated when populating this
>       /// vector, this information can contain them and therefore a
>       /// SCEVPredicate argument should be added to getExact.
> -    const SCEV *getExact(ScalarEvolution *SE,
> +    const SCEV *getExact(const Loop *L, ScalarEvolution *SE,
>                            SCEVUnionPredicate *Predicates = nullptr) const;
>   
>       /// Return the number of times this loop exit may fall through to the back
> 
> Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=328611&r1=328610&r2=328611&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
> +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Mar 27 00:30:38 2018
> @@ -6413,11 +6413,11 @@ const SCEV *ScalarEvolution::getExitCoun
>   const SCEV *
>   ScalarEvolution::getPredicatedBackedgeTakenCount(const Loop *L,
>                                                    SCEVUnionPredicate &Preds) {
> -  return getPredicatedBackedgeTakenInfo(L).getExact(this, &Preds);
> +  return getPredicatedBackedgeTakenInfo(L).getExact(L, this, &Preds);
>   }
>   
>   const SCEV *ScalarEvolution::getBackedgeTakenCount(const Loop *L) {
> -  return getBackedgeTakenInfo(L).getExact(this);
> +  return getBackedgeTakenInfo(L).getExact(L, this);
>   }
>   
>   /// Similar to getBackedgeTakenCount, except return the least SCEV value that is
> @@ -6474,8 +6474,8 @@ ScalarEvolution::getBackedgeTakenInfo(co
>     // must be cleared in this scope.
>     BackedgeTakenInfo Result = computeBackedgeTakenCount(L);
>   
> -  if (Result.getExact(this) != getCouldNotCompute()) {
> -    assert(isLoopInvariant(Result.getExact(this), L) &&
> +  if (Result.getExact(L, this) != getCouldNotCompute()) {
> +    assert(isLoopInvariant(Result.getExact(L, this), L) &&
>              isLoopInvariant(Result.getMax(this), L) &&
>              "Computed backedge-taken count isn't loop invariant for loop!");
>       ++NumTripCountsComputed;
> @@ -6656,20 +6656,30 @@ void ScalarEvolution::forgetValue(Value
>   /// caller's responsibility to specify the relevant loop exit using
>   /// getExact(ExitingBlock, SE).
>   const SCEV *
> -ScalarEvolution::BackedgeTakenInfo::getExact(ScalarEvolution *SE,
> +ScalarEvolution::BackedgeTakenInfo::getExact(const Loop *L, ScalarEvolution *SE,
>                                                SCEVUnionPredicate *Preds) const {
>     // If any exits were not computable, the loop is not computable.
>     if (!isComplete() || ExitNotTaken.empty())
>       return SE->getCouldNotCompute();
>   
>     const SCEV *BECount = nullptr;
> +  const BasicBlock *Latch = L->getLoopLatch();
> +  // All exits we have collected must dominate the only latch.
> +  if (!Latch)
> +    return SE->getCouldNotCompute();
> +
> +  // All exits we have gathered dominate loop's latch, so exact trip count is
> +  // simply a minimum out of all these calculated exit counts.
>     for (auto &ENT : ExitNotTaken) {
>       assert(ENT.ExactNotTaken != SE->getCouldNotCompute() && "bad exit SCEV");
> +    assert(SE->DT.dominates(ENT.ExitingBlock, Latch) &&
> +           "We should only have known counts for exits that dominate latch!");
>   
>       if (!BECount)
>         BECount = ENT.ExactNotTaken;
>       else if (BECount != ENT.ExactNotTaken)
> -      return SE->getCouldNotCompute();
> +      BECount = SE->getUMinFromMismatchedTypes(BECount, ENT.ExactNotTaken);
> +
>       if (Preds && !ENT.hasAlwaysTruePredicate())
>         Preds->add(ENT.Predicate.get());
>   
> 
> Added: llvm/trunk/test/Analysis/ScalarEvolution/exact_iter_count.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/exact_iter_count.ll?rev=328611&view=auto
> ==============================================================================
> --- llvm/trunk/test/Analysis/ScalarEvolution/exact_iter_count.ll (added)
> +++ llvm/trunk/test/Analysis/ScalarEvolution/exact_iter_count.ll Tue Mar 27 00:30:38 2018
> @@ -0,0 +1,27 @@
> +; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s
> +
> +; One side exit dominating the latch, exact backedge taken count is known.
> +define void @test_01() {
> +
> +; CHECK-LABEL: Determining loop execution counts for: @test_01
> +; CHECK-NEXT:  Loop %loop: <multiple exits> backedge-taken count is 50
> +
> +entry:
> +  br label %loop
> +
> +loop:
> +  %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
> +  %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
> +}
> 
> Modified: llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll?rev=328611&r1=328610&r2=328611&view=diff
> ==============================================================================
> --- llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll (original)
> +++ llvm/trunk/test/Analysis/ScalarEvolution/max-trip-count.ll Tue Mar 27 00:30:38 2018
> @@ -186,7 +186,7 @@ bar.exit:
>   ; MaxBECount should be the minimum of them.
>   ;
>   ; CHECK-LABEL: @two_mustexit
> -; CHECK: Loop %for.body.i: <multiple exits> Unpredictable backedge-taken count.
> +; CHECK: Loop %for.body.i: <multiple exits> backedge-taken count is 1
>   ; CHECK: Loop %for.body.i: max backedge-taken count is 1
>   define i32 @two_mustexit() {
>   entry:
> 
> Modified: llvm/trunk/test/Analysis/ScalarEvolution/trip-count14.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/trip-count14.ll?rev=328611&r1=328610&r2=328611&view=diff
> ==============================================================================
> --- llvm/trunk/test/Analysis/ScalarEvolution/trip-count14.ll (original)
> +++ llvm/trunk/test/Analysis/ScalarEvolution/trip-count14.ll Tue Mar 27 00:30:38 2018
> @@ -81,7 +81,7 @@ if.end:
>     br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
>   
>   ; CHECK-LABEL: Determining loop execution counts for: @s32_max2_unpredictable_exit
> -; CHECK-NEXT: Loop %do.body: <multiple exits> Unpredictable backedge-taken count.
> +; CHECK-NEXT: Loop %do.body: <multiple exits> backedge-taken count is (-1 + (-1 * ((-1 + (-1 * ((2 + %n) smax %n)) + %n) umax (-1 + (-1 * %x) + %n))))
>   ; CHECK-NEXT: Loop %do.body: max backedge-taken count is 2{{$}}
>   
>   do.end:
> @@ -169,7 +169,7 @@ if.end:
>     br i1 %cmp1, label %do.body, label %do.end ; taken either 0 or 2 times
>   
>   ; CHECK-LABEL: Determining loop execution counts for: @u32_max2_unpredictable_exit
> -; CHECK-NEXT: Loop %do.body: <multiple exits> Unpredictable backedge-taken count.
> +; CHECK-NEXT: Loop %do.body: <multiple exits> backedge-taken count is (-1 + (-1 * ((-1 + (-1 * ((2 + %n) umax %n)) + %n) umax (-1 + (-1 * %x) + %n))))
>   ; CHECK-NEXT: Loop %do.body: max backedge-taken count is 2{{$}}
>   
>   do.end:
> 
> Modified: llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate10.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate10.ll?rev=328611&r1=328610&r2=328611&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate10.ll (original)
> +++ llvm/trunk/test/Transforms/IndVarSimplify/loop_evaluate10.ll Tue Mar 27 00:30:38 2018
> @@ -3,11 +3,6 @@
>   ; This loop has multiple exits, and the value of %b1 depends on which
>   ; exit is taken. Indvars should correctly compute the exit values.
>   ;
> -; XFAIL: *
> -; Indvars does not currently replace loop invariant values unless all
> -; loop exits have the same exit value. We could handle some cases,
> -; such as this, by making getSCEVAtScope() sensitive to a particular
> -; loop exit.  See PR11388.
>   
>   target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
>   target triple = "x86_64-pc-linux-gnu"
> 
> Modified: llvm/trunk/test/Transforms/LoopSimplify/preserve-scev.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopSimplify/preserve-scev.ll?rev=328611&r1=328610&r2=328611&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/LoopSimplify/preserve-scev.ll (original)
> +++ llvm/trunk/test/Transforms/LoopSimplify/preserve-scev.ll Tue Mar 27 00:30:38 2018
> @@ -91,9 +91,9 @@ declare void @foo() nounwind
>   ; After simplifying, the max backedge count is refined.
>   ; Second SCEV print:
>   ; CHECK-LABEL: Determining loop execution counts for: @mergeExit
> -; CHECK: Loop %while.cond191: <multiple exits> Unpredictable backedge-taken count.
> +; CHECK: Loop %while.cond191: <multiple exits> backedge-taken count is 0
>   ; CHECK: Loop %while.cond191: max backedge-taken count is 0
> -; CHECK: Loop %while.cond191: Unpredictable predicated backedge-taken count.
> +; CHECK: Loop %while.cond191: Predicated backedge-taken count is 0
>   ; CHECK: Loop %while.cond191.outer: <multiple exits> Unpredictable backedge-taken count.
>   ; CHECK: Loop %while.cond191.outer: Unpredictable max backedge-taken count.
>   ; CHECK: Loop %while.cond191.outer: Unpredictable predicated backedge-taken count.
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
> 
-------------- next part --------------
target triple = "x86_64-unknown-linux-gnu"

define void @func_46() {
entry:
  br label %for.body2688.preheader

for.body2688.preheader:                           ; preds = %for.end2697, %entry
  %p_50.addr.0 = phi i16 [ undef, %entry ], [ %add2699, %for.end2697 ]
  %idxprom2690 = sext i16 %p_50.addr.0 to i32
  %arrayidx2691 = getelementptr inbounds [5 x i32], [5 x i32]* undef, i32 0, i32 %idxprom2690
  %0 = load i32, i32* %arrayidx2691, align 1
  %tobool2692 = icmp ne i32 %0, 0
  br label %for.body2688

for.body2688:                                     ; preds = %if.end2694, %for.body2688.preheader
  br i1 %tobool2692, label %for.end2697, label %if.end2694

if.end2694:                                       ; preds = %for.body2688
  br label %for.body2688

for.end2697:                                      ; preds = %for.body2688
  %add2699 = add nsw i16 %p_50.addr.0, 1
  br i1 false, label %for.body2688.preheader, label %for.cond2681.for.end2700_crit_edge

for.cond2681.for.end2700_crit_edge:               ; preds = %for.end2697
  unreachable
}


More information about the llvm-commits mailing list