From 2775c9a0dc42436fb4c6013c3037eaad335a7bd3 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Tue, 19 Mar 2024 04:20:16 -0400 Subject: [PATCH] Fix handling of virtual exit node in `PostDomTree` (#53739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an alternative to https://github.com/JuliaLang/julia/pull/53642 The `dom_edges()` for an exit block in the CFG are empty when computing the PostDomTree so the loop below this may not actually run. In that case, the right semidominator is the ancestor from the DFSTree, which is the "virtual" -1 block. This resolves half of the issue in https://github.com/JuliaLang/julia/issues/53613: ```julia julia> let code = Any[ # block 1 GotoIfNot(Argument(2), 3), # block 2 ReturnNode(Argument(3)), # block 3 (we should visit this block) Expr(:call, throw, "potential throw"), ReturnNode(), # unreachable ] ir = make_ircode(code; slottypes=Any[Any,Bool,Bool]) visited = BitSet() @test !Core.Compiler.visit_conditional_successors(CC.LazyPostDomtree(ir), ir, #=bb=#1) do succ::Int push!(visited, succ) return false end @test 2 ∈ visited @test 3 ∈ visited end Test Passed ``` This needs some tests (esp. since I don't think we have any DomTree tests at all right now), but otherwise should be good to go. --- base/compiler/ssair/domtree.jl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/base/compiler/ssair/domtree.jl b/base/compiler/ssair/domtree.jl index dfe0550d7a06d..bbae3a4d8c0fc 100644 --- a/base/compiler/ssair/domtree.jl +++ b/base/compiler/ssair/domtree.jl @@ -345,10 +345,7 @@ function SNCA!(domtree::GenericDomTree{IsPostDom}, blocks::Vector{BasicBlock}, m ancestors = copy(D.to_parent_pre) relevant_blocks = IsPostDom ? (1:max_pre) : (2:max_pre) for w::PreNumber in reverse(relevant_blocks) - # LLVM initializes this to the parent, the paper initializes this to - # `w`, but it doesn't really matter (the parent is a predecessor, so at - # worst we'll discover it below). Save a memory reference here. - semi_w = typemax(PreNumber) + semi_w = ancestors[w] last_linked = PreNumber(w + 1) for v ∈ dom_edges(domtree, blocks, D.from_pre[w]) # For the purpose of the domtree, ignore virtual predecessors into