[llvm] e399dd6 - [SimpleLoopUnswitch] Clear block and loop dispos after destroying loop.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 4 02:28:18 PDT 2022


Author: Florian Hahn
Date: 2022-10-04T10:27:52+01:00
New Revision: e399dd601f439ada0e505f380adf83d85d522f5a

URL: https://github.com/llvm/llvm-project/commit/e399dd601f439ada0e505f380adf83d85d522f5a
DIFF: https://github.com/llvm/llvm-project/commit/e399dd601f439ada0e505f380adf83d85d522f5a.diff

LOG: [SimpleLoopUnswitch] Clear block and loop dispos after destroying loop.

SimpleLoopUnswitch may remove loops. Clear block and loop dispositions,
to clean up invalid entries in the cache.

Fixes #58136.

Added: 
    llvm/test/Transforms/SimpleLoopUnswitch/invalidate-block-and-loop-dispositions.ll

Modified: 
    llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index e1d5bb5d6c8c..c1e67afb29e1 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -1820,7 +1820,8 @@ static SmallPtrSet<const BasicBlock *, 16> recomputeLoopBlockSet(Loop &L,
 /// referenced).
 static bool rebuildLoopAfterUnswitch(Loop &L, ArrayRef<BasicBlock *> ExitBlocks,
                                      LoopInfo &LI,
-                                     SmallVectorImpl<Loop *> &HoistedLoops) {
+                                     SmallVectorImpl<Loop *> &HoistedLoops,
+                                     ScalarEvolution *SE) {
   auto *PH = L.getLoopPreheader();
 
   // Compute the actual parent loop from the exit blocks. Because we may have
@@ -2013,6 +2014,8 @@ static bool rebuildLoopAfterUnswitch(Loop &L, ArrayRef<BasicBlock *> ExitBlocks,
       LI.removeLoop(llvm::find(LI, &L));
     // markLoopAsDeleted for L should be triggered by the caller (it is typically
     // done by using the UnswitchCB callback).
+    if (SE)
+      SE->forgetBlockAndLoopDispositions();
     LI.destroy(&L);
     return false;
   }
@@ -2380,7 +2383,8 @@ static void unswitchNontrivialInvariants(
     MSSAU->getMemorySSA()->verifyMemorySSA();
 
   SmallVector<Loop *, 4> HoistedLoops;
-  bool IsStillLoop = rebuildLoopAfterUnswitch(L, ExitBlocks, LI, HoistedLoops);
+  bool IsStillLoop =
+      rebuildLoopAfterUnswitch(L, ExitBlocks, LI, HoistedLoops, SE);
 
   if (MSSAU && VerifyMemorySSA)
     MSSAU->getMemorySSA()->verifyMemorySSA();

diff  --git a/llvm/test/Transforms/SimpleLoopUnswitch/invalidate-block-and-loop-dispositions.ll b/llvm/test/Transforms/SimpleLoopUnswitch/invalidate-block-and-loop-dispositions.ll
new file mode 100644
index 000000000000..b50611c1e627
--- /dev/null
+++ b/llvm/test/Transforms/SimpleLoopUnswitch/invalidate-block-and-loop-dispositions.ll
@@ -0,0 +1,85 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes="loop-mssa(loop-simplifycfg,require<iv-users>,licm,simple-loop-unswitch<nontrivial>)" -verify-scev -S %s | FileCheck %s
+target datalayout = "n16:32"
+
+ at glob = external global i16, align 1
+
+; Test case for PR58136.
+define void @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SRC:%.*]] = alloca i16, align 1
+; CHECK-NEXT:    [[DST:%.*]] = alloca float, align 1
+; CHECK-NEXT:    [[CALL:%.*]] = call i16 @foo()
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i16 8509, [[CALL]]
+; CHECK-NEXT:    [[L_1:%.*]] = load i16, ptr [[SRC]], align 1
+; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i16 [[L_1]], 10
+; CHECK-NEXT:    [[L_3:%.*]] = load i16, ptr [[SRC]], align 1
+; CHECK-NEXT:    [[GLOB_PROMOTED:%.*]] = load i16, ptr @glob, align 1
+; CHECK-NEXT:    [[DST_PROMOTED:%.*]] = load float, ptr [[DST]], align 1
+; CHECK-NEXT:    br i1 [[C_1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
+; CHECK:       entry.split.us:
+; CHECK-NEXT:    br i1 [[C_2]], label [[ENTRY_SPLIT_US_SPLIT_US:%.*]], label [[ENTRY_SPLIT_US_SPLIT:%.*]]
+; CHECK:       entry.split.us.split.us:
+; CHECK-NEXT:    br label [[LOOP_HEADER_US_US:%.*]]
+; CHECK:       loop.header.us.us:
+; CHECK-NEXT:    [[MUL1_US_US:%.*]] = phi i16 [ [[MUL_US_US:%.*]], [[LOOP_HEADER_US_US]] ], [ [[GLOB_PROMOTED]], [[ENTRY_SPLIT_US_SPLIT_US]] ]
+; CHECK-NEXT:    [[MUL_US_US]] = mul nsw i16 [[MUL1_US_US]], [[L_3]]
+; CHECK-NEXT:    br label [[LOOP_HEADER_US_US]]
+; CHECK:       entry.split.us.split:
+; CHECK-NEXT:    br label [[LOOP_HEADER_US:%.*]]
+; CHECK:       loop.header.us:
+; CHECK-NEXT:    br label [[EXIT_SPLIT_US:%.*]]
+; CHECK:       exit.split.us:
+; CHECK-NEXT:    [[DOTLCSSA_US:%.*]] = phi float [ [[DST_PROMOTED]], [[LOOP_HEADER_US]] ]
+; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK:       entry.split:
+; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[TMP0:%.*]] = phi float [ 1.000000e+01, [[LOOP_LATCH:%.*]] ], [ [[DST_PROMOTED]], [[ENTRY_SPLIT]] ]
+; CHECK-NEXT:    [[MUL1:%.*]] = phi i16 [ [[MUL:%.*]], [[LOOP_LATCH]] ], [ [[GLOB_PROMOTED]], [[ENTRY_SPLIT]] ]
+; CHECK-NEXT:    br i1 false, label [[LOOP_LATCH]], label [[EXIT_SPLIT:%.*]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[MUL]] = mul nsw i16 [[MUL1]], [[L_3]]
+; CHECK-NEXT:    store i16 [[MUL]], ptr @glob, align 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit.split:
+; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi float [ [[TMP0]], [[LOOP_HEADER]] ]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[DOTUS_PHI:%.*]] = phi float [ [[DOTLCSSA]], [[EXIT_SPLIT]] ], [ [[DOTLCSSA_US]], [[EXIT_SPLIT_US]] ]
+; CHECK-NEXT:    store float [[DOTUS_PHI]], ptr [[DST]], align 1
+; CHECK-NEXT:    ret void
+;
+entry:
+  %src = alloca i16, align 1
+  %dst = alloca float, align 1
+  br label %loop.header
+
+loop.header:
+  %call = call i16 @foo()
+  %c.1 = icmp ugt i16 8509, %call
+  br i1 %c.1, label %then.bb, label %merge.bb
+
+then.bb:
+  %l.1 = load i16, ptr %src, align 1
+  %c.2 = icmp slt i16 %l.1, 10
+  br label %merge.bb
+
+merge.bb:
+  %p = phi i1 [ false, %loop.header ], [ %c.2, %then.bb ]
+  br i1 %p, label %loop.latch, label %exit
+
+loop.latch:
+  %l.2 = load i16, ptr @glob, align 1
+  %l.3 = load i16, ptr %src, align 1
+  %mul = mul nsw i16 %l.2, %l.3
+  store i16 %mul, ptr @glob, align 1
+  store float 10.0, ptr %dst, align 1
+  br label %loop.header
+
+exit:
+  ret void
+}
+
+declare i16 @foo() nounwind readnone


        


More information about the llvm-commits mailing list