From c1c6c64ab46271b5b8182b7366d3d2c629c9798d Mon Sep 17 00:00:00 2001 From: Philip Reames 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 &VisitedBlocks, unsigned Depth) { + + assert(SE.DT.isReachableFromEntry(Block) && SE.DT.isReachableFromEntry(Pred)); + SmallVector 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 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 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 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 }