[llvm] ea7ab5a - [IndVarSimplify] Notify top most loop to drop cached exit counts

Andrew Wei via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 18 23:57:40 PST 2020


Author: Andrew Wei
Date: 2020-11-19T15:37:54+08:00
New Revision: ea7ab5a42cd4ab236977c4fe64768641fd506fd7

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

LOG: [IndVarSimplify] Notify top most loop to drop cached exit counts

Some nested loops may share the same ExitingBB, so after we finishing FoldExit,
we need to notify OuterLoop and SCEV to drop any stored trip count.

Patched by: guopeilin
Reviewed By: mkazantsev

Differential Revision: https://reviews.llvm.org/D91325

Added: 
    llvm/test/Transforms/IndVarSimplify/shared-exit-between-nested-loop.ll

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index d9a959d2fb6d..5ff4c9ad18f4 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -1790,7 +1790,9 @@ bool IndVarSimplify::run(Loop *L) {
   if (optimizeLoopExits(L, Rewriter))  {
     Changed = true;
     // Given we've changed exit counts, notify SCEV
-    SE->forgetLoop(L);
+    // Some nested loops may share same folded exit basic block,
+    // thus we need to notify top most loop.
+    SE->forgetTopmostLoop(L);
   }
 
   // Try to form loop invariant tests for loop exits by changing how many

diff  --git a/llvm/test/Transforms/IndVarSimplify/shared-exit-between-nested-loop.ll b/llvm/test/Transforms/IndVarSimplify/shared-exit-between-nested-loop.ll
new file mode 100644
index 000000000000..f35310708ce0
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/shared-exit-between-nested-loop.ll
@@ -0,0 +1,64 @@
+; RUN: opt -indvars -S < %s | FileCheck %s
+
+ at __const.e.f = private unnamed_addr constant <{ <{ [2 x i32], [2 x i32], [8 x [2 x i32]] }>, [10 x [2 x i32]] }> <{ <{ [2 x i32], [2 x i32], [8 x [2 x i32]] }> <{ [2 x i32] [i32 4, i32 8], [2 x i32] [i32 3, i32 10], [8 x [2 x i32]] zeroinitializer }>, [10 x [2 x i32]] [[2 x i32] zeroinitializer, [2 x i32] zeroinitializer, [2 x i32] [i32 1, i32 5], [2 x i32] [i32 2080555007, i32 0], [2 x i32] zeroinitializer, [2 x i32] zeroinitializer, [2 x i32] zeroinitializer, [2 x i32] zeroinitializer, [2 x i32] zeroinitializer, [2 x i32] zeroinitializer] }>, align 4
+
+define dso_local i8 @main() local_unnamed_addr {
+entry:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:                              ; preds = %for.inc15, %entry
+  %storemerge32 = phi i32 [ 0, %entry ], [ %inc16, %for.inc15 ]
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc, %for.cond1.preheader
+  %storemerge2531 = phi i32 [ 0, %for.cond1.preheader ], [ %inc, %for.inc ]
+  %tobool = icmp eq i32 1, 0
+  br i1 %tobool, label %cleanup, label %if.then
+
+if.then:                                          ; preds = %for.cond4
+; CHECK:        if.then:                                          ; preds = %for.cond4
+; CHECK-NEXT:     br i1 false, label %cleanup, label %for.inc
+  %add = add nuw nsw i32 %storemerge2531, 2
+  %idxprom8 = zext i32 %add to i64
+  %arrayidx10 = getelementptr inbounds <{ <{ [2 x i32], [2 x i32], [8 x [2 x i32]] }>, [10 x [2 x i32]] }>, <{ <{ [2 x i32], [2 x i32], [8 x [2 x i32]] }>, [10 x [2 x i32]] }>* @__const.e.f, i64 0, i32 1, i64 %idxprom8, i64 0
+  %0 = load i32, i32* %arrayidx10, align 4
+  %tobool11 = icmp eq i32 %0, 0
+  br i1 %tobool11, label %cleanup, label %for.inc
+
+for.inc:                                          ; preds = %if.then
+  %inc = add nuw nsw i32 %storemerge2531, 1
+  %cmp2 = icmp ult i32 %inc, 2
+  br i1 %cmp2, label %for.cond4, label %for.inc15
+
+cleanup:                                          ; preds = %if.then, %for.cond4
+  br label %return
+
+for.inc15:                                        ; preds = %for.inc
+; CHECK:        for.inc15:
+; CHECK-NEXT:     %inc16 = add nuw nsw i32 %storemerge32, 1
+; CHECK-NEXT:     %cmp = icmp eq i32 %inc16, 4
+; CHECK-NEXT:     br i1 %cmp, label %for.cond18thread-pre-split, label %for.cond1.preheader
+  %inc16 = add nuw nsw i32 %storemerge32, 1
+  %cmp = icmp eq i32 %inc16, 4
+  br i1 %cmp, label %for.cond18thread-pre-split, label %for.cond1.preheader
+
+for.cond18thread-pre-split:                       ; preds = %for.inc15
+  br i1 1, label %return.loopexit, label %for.inc21.lr.ph
+
+for.inc21.lr.ph:                                  ; preds = %for.cond18thread-pre-split
+  br label %for.inc21
+
+for.inc21:                                        ; preds = %for.inc21, %for.inc21.lr.ph
+  %1 = phi i32 [ undef, %for.inc21.lr.ph ], [ %inc22, %for.inc21 ]
+  %inc22 = add nsw i32 %1, 1
+  br i1 true, label %for.cond18.return.loopexit_crit_edge, label %for.inc21
+
+for.cond18.return.loopexit_crit_edge:             ; preds = %for.inc21
+  br label %return.loopexit
+
+return.loopexit:                                  ; preds = %for.cond18.return.loopexit_crit_edge, %for.cond18thread-pre-split
+  br label %return
+
+return:                                           ; preds = %return.loopexit, %cleanup
+  ret i8 undef
+}


        


More information about the llvm-commits mailing list