[llvm] [SCEV] Fix a hang introduced by collectForPHI (PR #158153)

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 12 08:16:09 PDT 2025


https://github.com/preames updated https://github.com/llvm/llvm-project/pull/158153

>From c1c6c64ab46271b5b8182b7366d3d2c629c9798d Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Thu, 11 Sep 2025 14:03:27 -0700
Subject: [PATCH 1/4] [SCEV] Fix an compiler hang introduced by collectForPHI

If we have a phi where one of it's source blocks is an unreachable
block, we don't want to traverse back into the unreachable region.
Doing so allows e.g. finding a trivial self loop when walking back
the predecessor chain.
---
 llvm/lib/Analysis/ScalarEvolution.cpp         |  9 ++++++
 ...t-guard-info-with-multiple-predecessors.ll | 31 +++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 34e497d9ea3cb..8c48ffbf1a049 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -15445,6 +15445,12 @@ void ScalarEvolution::LoopGuards::collectFromPHI(
     const BasicBlock *InBlock = Phi.getIncomingBlock(IncomingIdx);
     if (!VisitedBlocks.insert(InBlock).second)
       return {nullptr, scCouldNotCompute};
+
+    // Avoid analyzing unreachable blocks so that we don't get trapped
+    // traversing cycles with ill-formed dominance or infinite cycles
+    if (!SE.DT.isReachableFromEntry(InBlock))
+      return {nullptr, scCouldNotCompute};
+
     auto [G, Inserted] = IncomingGuards.try_emplace(InBlock, LoopGuards(SE));
     if (Inserted)
       collectFromBlock(SE, G->second, Phi.getParent(), InBlock, VisitedBlocks,
@@ -15499,6 +15505,9 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
     ScalarEvolution &SE, ScalarEvolution::LoopGuards &Guards,
     const BasicBlock *Block, const BasicBlock *Pred,
     SmallPtrSetImpl<const BasicBlock *> &VisitedBlocks, unsigned Depth) {
+
+  assert(SE.DT.isReachableFromEntry(Block) && SE.DT.isReachableFromEntry(Pred));
+
   SmallVector<const SCEV *> ExprsToRewrite;
   auto CollectCondition = [&](ICmpInst::Predicate Predicate, const SCEV *LHS,
                               const SCEV *RHS,
diff --git a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
index 28035b05303db..13762e3fa0474 100644
--- a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
+++ b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
@@ -364,3 +364,34 @@ body:
 exit:
   ret void
 }
+
+define void @hang_due_to_unreachable_phi_inblock() personality ptr null {
+  br label %1
+
+1:                                                ; preds = %1, %0
+  %2 = invoke ptr null(i64 0)
+          to label %1 unwind label %3
+
+3:                                                ; preds = %1
+  %4 = landingpad { ptr, i32 }
+          cleanup
+  br label %7
+
+5:                                                ; No predecessors!
+  %6 = landingpad { ptr, i32 }
+          cleanup
+  br label %7
+
+7:                                                ; preds = %5, %3
+  %8 = phi ptr [ null, %5 ], [ null, %3 ]
+  br i1 false, label %13, label %9
+
+9:                                                ; preds = %9, %7
+  %10 = phi ptr [ %11, %9 ], [ null, %7 ]
+  %11 = getelementptr i8, ptr %10, i64 24
+  %12 = icmp eq ptr %10, null
+  br i1 %12, label %13, label %9
+
+13:                                               ; preds = %9, %7
+  resume { ptr, i32 } zeroinitializer
+}

>From a7133dd7a21bd6a1398175c038fd6c1173c2ed12 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Fri, 12 Sep 2025 08:05:38 -0700
Subject: [PATCH 2/4] Minimal change to actually hand on old opt

---
 ...dge-taken-count-guard-info-with-multiple-predecessors.ll | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
index 13762e3fa0474..75b1d9fe2242d 100644
--- a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
+++ b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
@@ -377,7 +377,11 @@ define void @hang_due_to_unreachable_phi_inblock() personality ptr null {
           cleanup
   br label %7
 
-5:                                                ; No predecessors!
+self-loop:                                                ; preds = %1, %0
+  %dead = invoke ptr null(i64 0)
+          to label %self-loop unwind label %5
+
+5:                                                ; preds = %self-loop
   %6 = landingpad { ptr, i32 }
           cleanup
   br label %7

>From 7dee654bf9b52c4b005600b4f35abc9959205152 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Fri, 12 Sep 2025 08:07:39 -0700
Subject: [PATCH 3/4] instnamer for hand reduce

---
 ...t-guard-info-with-multiple-predecessors.ll | 45 ++++++++++---------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
index 75b1d9fe2242d..d71c32f1736e6 100644
--- a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
+++ b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
@@ -366,36 +366,37 @@ exit:
 }
 
 define void @hang_due_to_unreachable_phi_inblock() personality ptr null {
-  br label %1
+bb:
+  br label %bb1
 
-1:                                                ; preds = %1, %0
-  %2 = invoke ptr null(i64 0)
-          to label %1 unwind label %3
+bb1:                                              ; preds = %bb1, %bb
+  %i = invoke ptr null()
+          to label %bb1 unwind label %bb2
 
-3:                                                ; preds = %1
-  %4 = landingpad { ptr, i32 }
+bb2:                                              ; preds = %bb1
+  %i3 = landingpad { ptr, i32 }
           cleanup
-  br label %7
+  br label %bb6
 
-self-loop:                                                ; preds = %1, %0
-  %dead = invoke ptr null(i64 0)
-          to label %self-loop unwind label %5
+self-loop:                                        ; preds = %self-loop
+  %dead = invoke ptr null()
+          to label %self-loop unwind label %bb4
 
-5:                                                ; preds = %self-loop
-  %6 = landingpad { ptr, i32 }
+bb4:                                              ; preds = %self-loop
+  %i5 = landingpad { ptr, i32 }
           cleanup
-  br label %7
+  br label %bb6
 
-7:                                                ; preds = %5, %3
-  %8 = phi ptr [ null, %5 ], [ null, %3 ]
-  br i1 false, label %13, label %9
+bb6:                                              ; preds = %bb4, %bb2
+  %i7 = phi ptr [ null, %bb4 ], [ null, %bb2 ]
+  br i1 false, label %bb12, label %bb8
 
-9:                                                ; preds = %9, %7
-  %10 = phi ptr [ %11, %9 ], [ null, %7 ]
-  %11 = getelementptr i8, ptr %10, i64 24
-  %12 = icmp eq ptr %10, null
-  br i1 %12, label %13, label %9
+bb8:                                              ; preds = %bb8, %bb6
+  %i9 = phi ptr [ %i10, %bb8 ], [ null, %bb6 ]
+  %i10 = getelementptr i8, ptr %i9, i64 24
+  %i11 = icmp eq ptr %i9, null
+  br i1 %i11, label %bb12, label %bb8
 
-13:                                               ; preds = %9, %7
+bb12:                                             ; preds = %bb8, %bb6
   resume { ptr, i32 } zeroinitializer
 }

>From 074ecdcc506a886df7ffec9bf9e6d59e78f1a260 Mon Sep 17 00:00:00 2001
From: Philip Reames <preames at rivosinc.com>
Date: Fri, 12 Sep 2025 08:12:21 -0700
Subject: [PATCH 4/4] Further hand reduction

---
 ...t-guard-info-with-multiple-predecessors.ll | 20 +++++--------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
index d71c32f1736e6..564ce6b7d622f 100644
--- a/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
+++ b/llvm/test/Analysis/ScalarEvolution/backedge-taken-count-guard-info-with-multiple-predecessors.ll
@@ -367,15 +367,6 @@ exit:
 
 define void @hang_due_to_unreachable_phi_inblock() personality ptr null {
 bb:
-  br label %bb1
-
-bb1:                                              ; preds = %bb1, %bb
-  %i = invoke ptr null()
-          to label %bb1 unwind label %bb2
-
-bb2:                                              ; preds = %bb1
-  %i3 = landingpad { ptr, i32 }
-          cleanup
   br label %bb6
 
 self-loop:                                        ; preds = %self-loop
@@ -387,16 +378,15 @@ bb4:                                              ; preds = %self-loop
           cleanup
   br label %bb6
 
-bb6:                                              ; preds = %bb4, %bb2
-  %i7 = phi ptr [ null, %bb4 ], [ null, %bb2 ]
-  br i1 false, label %bb12, label %bb8
+bb6:                                              ; preds = %bb4, %bb
+  %i7 = phi ptr [ null, %bb4 ], [ null, %bb ]
+  br label %bb8
 
 bb8:                                              ; preds = %bb8, %bb6
-  %i9 = phi ptr [ %i10, %bb8 ], [ null, %bb6 ]
-  %i10 = getelementptr i8, ptr %i9, i64 24
+  %i9 = phi ptr [ null, %bb8 ], [ null, %bb6 ]
   %i11 = icmp eq ptr %i9, null
   br i1 %i11, label %bb12, label %bb8
 
 bb12:                                             ; preds = %bb8, %bb6
-  resume { ptr, i32 } zeroinitializer
+  ret void
 }



More information about the llvm-commits mailing list