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

Maxim Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Wed May 2 18:29:22 PDT 2018


Thanks for letting me know Mikael! I will take a look into this asap.

-- Max

-----Original Message-----
From: Mikael Holmén [mailto:mikael.holmen at ericsson.com] 
Sent: Monday, April 30, 2018 3:39 PM
To: Maxim Kazantsev <max.kazantsev at azul.com>
Cc: llvm-commits at lists.llvm.org
Subject: Re: [llvm] r328611 - [SCEV] Make exact taken count calculation more optimistic

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/S
> calarEvolution.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/ScalarEvol
> ution.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/ScalarEvo
> lution/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/ScalarEvo
> lution/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/ScalarEvo
> lution/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/IndVarS
> implify/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/LoopSim
> plify/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
> 


More information about the llvm-commits mailing list