[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