[llvm] [SCEV] Fix exit condition for recursive loop guard collection (PR #120442)

Julian Nagele via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 20 01:17:23 PST 2024


https://github.com/juliannagele updated https://github.com/llvm/llvm-project/pull/120442

>From 057a47aaaf256c3a9d1c8dab442bc03fe6aa5c60 Mon Sep 17 00:00:00 2001
From: Julian Nagele <j.nagele at apple.com>
Date: Wed, 18 Dec 2024 16:30:13 +0100
Subject: [PATCH 1/3] [SCEV] Fix exit condition for recursive loop guard
 collection

When assumptions are present Terms.size() does not actually count the
number of conditions collected from dominating branches; introduce a
separate counter.
---
 llvm/lib/Analysis/ScalarEvolution.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index d55d09020fc147..6ba91c4417f724 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -15753,6 +15753,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
   // predecessors that can be found that have unique successors leading to the
   // original header.
   // TODO: share this logic with isLoopEntryGuardedByCond.
+  unsigned NumCollectedConditions = 0;
   std::pair<const BasicBlock *, const BasicBlock *> Pair(Pred, Block);
   for (; Pair.first;
        Pair = SE.getPredecessorWithUniqueSuccessorForBB(Pair.first)) {
@@ -15767,7 +15768,7 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
 
     // If we are recursively collecting guards stop after 2
     // predecessors to limit compile-time impact for now.
-    if (Depth > 0 && Terms.size() == 2)
+    if (Depth > 0 && ++NumCollectedConditions == 2)
       break;
   }
   // Finally, if we stopped climbing the predecessor chain because

>From a276fdf1b701917edc89ec01e2ad65bc86e7297a Mon Sep 17 00:00:00 2001
From: Julian Nagele <j.nagele at apple.com>
Date: Wed, 18 Dec 2024 17:13:29 +0100
Subject: [PATCH 2/3] fixup! [SCEV] Fix exit condition for recursive loop guard
 collection

Add test
---
 .../test/Analysis/ScalarEvolution/pr120442.ll | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 llvm/test/Analysis/ScalarEvolution/pr120442.ll

diff --git a/llvm/test/Analysis/ScalarEvolution/pr120442.ll b/llvm/test/Analysis/ScalarEvolution/pr120442.ll
new file mode 100644
index 00000000000000..66f06f551323b8
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/pr120442.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -disable-output "-passes=print<scalar-evolution>" -scalar-evolution-max-iterations=0  -scalar-evolution-classify-expressions=0  2>&1 | FileCheck %s
+
+declare void @llvm.assume(i1)
+
+define void @pr120442() {
+; CHECK-LABEL: 'pr120442'
+; CHECK-NEXT:  Determining loop execution counts for: @pr120442
+; CHECK-NEXT:  Loop %bb2: backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb2: constant max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb2: symbolic max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %bb2: Trip multiple is 1
+; CHECK-NEXT:  Loop %bb1: <multiple exits> Unpredictable backedge-taken count.
+; CHECK-NEXT:  Loop %bb1: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT:  Loop %bb1: Unpredictable symbolic max backedge-taken count.
+bb:
+  call void @llvm.assume(i1 false)
+  call void @llvm.assume(i1 false)
+  br label %bb6
+
+bb1:
+  br label %bb2
+
+bb2:
+  %phi = phi i32 [ %add, %bb2 ], [ 0, %bb1 ]
+  %add = add i32 %phi, 1
+  %icmp = icmp ugt i32 %add, 0
+  br i1 %icmp, label %bb1, label %bb2
+
+bb5:
+  br i1 false, label %bb6, label %bb5
+
+bb6:
+  %phi7 = phi i32 [ 0, %bb5 ], [ 0, %bb ]
+  br label %bb1
+}

>From a2b7e865a3ecbb7ee854df2589c3f172ccc98352 Mon Sep 17 00:00:00 2001
From: Julian Nagele <j.nagele at apple.com>
Date: Fri, 20 Dec 2024 10:17:02 +0100
Subject: [PATCH 3/3] fixup! fixup! [SCEV] Fix exit condition for recursive
 loop guard collection

---
 llvm/lib/Analysis/ScalarEvolution.cpp         |  5 ++-
 .../test/Analysis/ScalarEvolution/pr120442.ll | 45 +++++++++----------
 2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 6ba91c4417f724..1e4bb1d606cd39 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -15765,10 +15765,11 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
 
     Terms.emplace_back(LoopEntryPredicate->getCondition(),
                        LoopEntryPredicate->getSuccessor(0) == Pair.second);
+    NumCollectedConditions++;
 
     // If we are recursively collecting guards stop after 2
-    // predecessors to limit compile-time impact for now.
-    if (Depth > 0 && ++NumCollectedConditions == 2)
+    // conditions to limit compile-time impact for now.
+    if (Depth > 0 && NumCollectedConditions == 2)
       break;
   }
   // Finally, if we stopped climbing the predecessor chain because
diff --git a/llvm/test/Analysis/ScalarEvolution/pr120442.ll b/llvm/test/Analysis/ScalarEvolution/pr120442.ll
index 66f06f551323b8..fc4f493e6503cc 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr120442.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr120442.ll
@@ -2,34 +2,33 @@
 
 declare void @llvm.assume(i1)
 
-define void @pr120442() {
+; Checks that the presence of assumptions does not interfere with
+; exiting loop guard collection via following loop predecessors.
+define void @pr120442(i1 %c.1, i1 %c.2) {
 ; CHECK-LABEL: 'pr120442'
 ; CHECK-NEXT:  Determining loop execution counts for: @pr120442
-; CHECK-NEXT:  Loop %bb2: backedge-taken count is i32 0
-; CHECK-NEXT:  Loop %bb2: constant max backedge-taken count is i32 0
-; CHECK-NEXT:  Loop %bb2: symbolic max backedge-taken count is i32 0
-; CHECK-NEXT:  Loop %bb2: Trip multiple is 1
-; CHECK-NEXT:  Loop %bb1: <multiple exits> Unpredictable backedge-taken count.
-; CHECK-NEXT:  Loop %bb1: Unpredictable constant max backedge-taken count.
-; CHECK-NEXT:  Loop %bb1: Unpredictable symbolic max backedge-taken count.
-bb:
-  call void @llvm.assume(i1 false)
-  call void @llvm.assume(i1 false)
-  br label %bb6
+; CHECK-NEXT:  Loop %inner.header: backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %inner.header: constant max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %inner.header: symbolic max backedge-taken count is i32 0
+; CHECK-NEXT:  Loop %inner.header: Trip multiple is 1
+entry:
+  call void @llvm.assume(i1 %c.1)
+  call void @llvm.assume(i1 %c.2)
+  br label %outer.header
+
+outer.header:
+  %phi7 = phi i32 [ 0, %bb ], [ 0, %entry ]
+  br label %inner.header
 
-bb1:
-  br label %bb2
+bb:
+  br i1 false, label %outer.header, label %bb
 
-bb2:
-  %phi = phi i32 [ %add, %bb2 ], [ 0, %bb1 ]
+inner.header:
+  %phi = phi i32 [ %add, %inner.header ], [ 0, %outer.header ]
   %add = add i32 %phi, 1
   %icmp = icmp ugt i32 %add, 0
-  br i1 %icmp, label %bb1, label %bb2
-
-bb5:
-  br i1 false, label %bb6, label %bb5
+  br i1 %icmp, label %exit, label %inner.header
 
-bb6:
-  %phi7 = phi i32 [ 0, %bb5 ], [ 0, %bb ]
-  br label %bb1
+exit:
+  ret void
 }



More information about the llvm-commits mailing list