[PATCH] D134167: [LoopRotate] Drop loop dispositions when rotationg loops. PR56260

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 19 01:08:21 PDT 2022


mkazantsev created this revision.
mkazantsev added reviewers: fhahn, zhendongsu, nikic, lebedev.ri, reames.
Herald added subscribers: javed.absar, hiraditya.
Herald added a project: All.
mkazantsev requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This is required because if there is a pure loop-invariant instruction, Loop Rotation
may decide to not clone it and just hoist it instead. If SCEV has previously cached
that it was loop-variant (not being smart enough to prove invariance), we may end
up with inconsistent cache state (which may later trigger false-negative assertion
failures checking that something was invariant).

This is a conservative fix that unconditionally drops the dispositions. We could
only drop it if the hoisting has actually happened, but it should take some time
understanding whether it's safe with all other things this function does.


https://reviews.llvm.org/D134167

Files:
  llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
  llvm/test/Transforms/LoopRotate/pr56260.ll


Index: llvm/test/Transforms/LoopRotate/pr56260.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/LoopRotate/pr56260.ll
@@ -0,0 +1,58 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes='loop(loop-rotate,loop-deletion)' -S | FileCheck %s
+
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @main() {
+; CHECK-LABEL: @main(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[L0_PREHEADER:%.*]]
+; CHECK:       L0.L0.preheader.loopexit_crit_edge:
+; CHECK-NEXT:    br label [[L0_PREHEADER_LOOPEXIT:%.*]]
+; CHECK:       L0.preheader.loopexit:
+; CHECK-NEXT:    br label [[L0_PREHEADER]]
+; CHECK:       L0.preheader:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 0, 0
+; CHECK-NEXT:    [[INC:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT:    [[SPEC_SELECT1:%.*]] = add nsw i32 0, [[INC]]
+; CHECK-NEXT:    [[TOBOOL3_NOT2:%.*]] = icmp eq i32 [[SPEC_SELECT1]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL3_NOT2]], label [[L0_PREHEADER_LOOPEXIT]], label [[L1_PREHEADER_LR_PH:%.*]]
+; CHECK:       L1.preheader.lr.ph:
+; CHECK-NEXT:    br label [[L1_PREHEADER:%.*]]
+; CHECK:       L1.preheader:
+; CHECK-NEXT:    [[SPEC_SELECT4:%.*]] = phi i32 [ [[SPEC_SELECT1]], [[L1_PREHEADER_LR_PH]] ], [ [[SPEC_SELECT:%.*]], [[L0_LATCH:%.*]] ]
+; CHECK-NEXT:    [[K_03:%.*]] = phi i32 [ 0, [[L1_PREHEADER_LR_PH]] ], [ [[SPEC_SELECT4]], [[L0_LATCH]] ]
+; CHECK-NEXT:    [[TOBOOL8_NOT:%.*]] = icmp eq i32 [[K_03]], 0
+; CHECK-NEXT:    br label [[L0_LATCH]]
+; CHECK:       L0.latch:
+; CHECK-NEXT:    [[SPEC_SELECT]] = add nsw i32 [[SPEC_SELECT4]], [[INC]]
+; CHECK-NEXT:    [[TOBOOL3_NOT:%.*]] = icmp eq i32 [[SPEC_SELECT]], 0
+; CHECK-NEXT:    br i1 [[TOBOOL3_NOT]], label [[L0_L0_PREHEADER_LOOPEXIT_CRIT_EDGE:%.*]], label [[L1_PREHEADER]]
+;
+entry:
+  br label %L0.preheader
+
+L0.preheader:
+  br label %L0
+
+L0:                                               ; preds = %L0.latch, %L0.preheader
+  %k.0 = phi i32 [ 0, %L0.preheader ], [ %spec.select, %L0.latch ]
+  %cmp = icmp slt i32 0, 0
+  %inc = zext i1 %cmp to i32
+  %spec.select = add nsw i32 %k.0, %inc
+  %tobool3.not = icmp eq i32 %spec.select, 0
+  br i1 %tobool3.not, label %L0.preheader, label %L1.preheader
+
+L1.preheader:
+  %tobool8.not = icmp eq i32 %k.0, 0
+  br label %L1
+
+L1:
+  br i1 %tobool8.not, label %L1.latch, label %L0.latch
+
+L1.latch:
+  br i1 false, label %L1, label %L0.latch
+
+L0.latch:
+  br label %L0
+}
Index: llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
===================================================================
--- llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
+++ llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
@@ -345,8 +345,12 @@
     // all outer loops because insertion and deletion of blocks that happens
     // during the rotation may violate invariants related to backedge taken
     // infos in them.
-    if (SE)
+    if (SE) {
       SE->forgetTopmostLoop(L);
+      // We may hoist some instructions out of loop. In case if they were cached
+      // as "loop variant" or "loop computable", these caches must be dropped.
+      SE->forgetLoopDispositions();
+    }
 
     LLVM_DEBUG(dbgs() << "LoopRotation: rotating "; L->dump());
     if (MSSAU && VerifyMemorySSA)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134167.461157.patch
Type: text/x-patch
Size: 3334 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220919/aea081a8/attachment.bin>


More information about the llvm-commits mailing list