[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:05:55 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/2] [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/2] 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
More information about the llvm-commits
mailing list