From a03c5cd49047ae9815f5242794537e9b5cc0a075 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 1edb8d2d5c6d4..2f22da04f9804 100644 --- a/base/compiler/ssair/domtree.jl +++ b/base/compiler/ssair/domtree.jl @@ -332,10 +332,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