[PATCH] D134612: [LoopUnroll] Forget block and loop dispositions during unrolling.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 25 13:12:15 PDT 2022
fhahn created this revision.
fhahn added reviewers: nikic, reames, mkazantsev.
Herald added subscribers: javed.absar, zzheng, hiraditya.
Herald added a project: All.
fhahn requested review of this revision.
Herald added a project: LLVM.
After unrolling a loop, the block and loop dispositions need to be
cleared. As we don't know which SCEVs in the loop/blocks may be
impacted, completely clear the cache. This should also fix some cases
where deleted loops remained in the LoopDispositions cache.
This fixes a verification failure surfaced by D134531 <https://reviews.llvm.org/D134531>.
I am planning on reviewing/updating the existing uses of
forgetLoopDispositions to check if they should be replaced by
forgetBlockAndLoopDispositions.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D134612
Files:
llvm/include/llvm/Analysis/ScalarEvolution.h
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/lib/Transforms/Utils/LoopUnroll.cpp
llvm/test/Transforms/LoopUnroll/loop-block-disposition-after-full-unroll.ll
Index: llvm/test/Transforms/LoopUnroll/loop-block-disposition-after-full-unroll.ll
===================================================================
--- llvm/test/Transforms/LoopUnroll/loop-block-disposition-after-full-unroll.ll
+++ llvm/test/Transforms/LoopUnroll/loop-block-disposition-after-full-unroll.ll
@@ -1,9 +1,28 @@
-; RUN: opt -passes='loop(indvars,loop-deletion,loop-unroll-full),verify<scalar-evolution>' -S %s
-
-; XFAIL: *
-; FIXME: currently fails verification.
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes='loop(indvars,loop-deletion,loop-unroll-full),verify<scalar-evolution>' -S %s | FileCheck %s
define void @test(i1 %c.0, ptr %A) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C_0:%.*]], label [[LOOP_1_HEADER_PREHEADER:%.*]], label [[OUTER_HEADER_PREHEADER:%.*]]
+; CHECK: outer.header.preheader:
+; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
+; CHECK: loop.1.header.preheader:
+; CHECK-NEXT: br label [[LOOP_1_HEADER:%.*]]
+; CHECK: loop.1.header:
+; CHECK-NEXT: store i32 0, ptr [[A:%.*]], align 4
+; CHECK-NEXT: br label [[LOOP_1_LATCH:%.*]]
+; CHECK: loop.1.latch:
+; CHECK-NEXT: store i32 0, ptr [[A]], align 4
+; CHECK-NEXT: br label [[LOOP_1_LATCH_1:%.*]]
+; CHECK: loop.1.latch.1:
+; CHECK-NEXT: ret void
+; CHECK: outer.header.loopexit:
+; CHECK-NEXT: br label [[OUTER_HEADER]]
+; CHECK: outer.header:
+; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
+; CHECK-NEXT: br label [[OUTER_HEADER_LOOPEXIT:%.*]]
+;
entry:
br i1 %c.0, label %loop.1.header, label %outer.header
Index: llvm/lib/Transforms/Utils/LoopUnroll.cpp
===================================================================
--- llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -467,6 +467,7 @@
SE->forgetAllLoops();
else
SE->forgetTopmostLoop(L);
+ SE->forgetBlockAndLoopDispositions();
}
if (!LatchIsExiting)
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8384,6 +8384,8 @@
void ScalarEvolution::forgetLoopDispositions() { LoopDispositions.clear(); }
+void ScalarEvolution::forgetBlockAndLoopDispositions() { BlockDispositions.clear(); LoopDispositions.clear();}
+
/// Get the exact loop backedge taken count considering all loop exits. A
/// computable result can only be returned for loops with all exiting blocks
/// dominating the latch. howFarToZero assumes that the limit of each loop test
Index: llvm/include/llvm/Analysis/ScalarEvolution.h
===================================================================
--- llvm/include/llvm/Analysis/ScalarEvolution.h
+++ llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -939,6 +939,13 @@
/// recompute is simpler.
void forgetLoopDispositions();
+ /// Called when the client has changed the disposition of values in
+ /// a loop or block.
+ ///
+ /// We don't have a way to invalidate per-loop/per-block dispositions. Clear and
+ /// recompute is simpler.
+ void forgetBlockAndLoopDispositions();
+
/// Determine the minimum number of zero bits that S is guaranteed to end in
/// (at every loop iteration). It is, at the same time, the minimum number
/// of times S is divisible by 2. For example, given {4,+,8} it returns 2.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134612.462757.patch
Type: text/x-patch
Size: 3488 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220925/2300205f/attachment.bin>
More information about the llvm-commits
mailing list