[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