From 95a379219baa4f4b747cff0c9a739e611d11b0e5 Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:34:43 -0400 Subject: [PATCH] Handle no-postdominator case in finalizer pass (#54765) This pass was assuming that the post-dominator of all finalizer uses exists as a real BB in the CFG. Resolves https://github.com/JuliaLang/julia/issues/54596 (cherry picked from commit 6ec2b1fb46dc6c41cbb5eb6973f6a2cae4682538) --- base/compiler/ssair/domtree.jl | 2 ++ base/compiler/ssair/passes.jl | 1 + test/compiler/irpasses.jl | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/base/compiler/ssair/domtree.jl b/base/compiler/ssair/domtree.jl index bbae3a4d8c0fc..5c78809675a56 100644 --- a/base/compiler/ssair/domtree.jl +++ b/base/compiler/ssair/domtree.jl @@ -657,6 +657,8 @@ end Compute the nearest common (post-)dominator of `a` and `b`. """ function nearest_common_dominator(domtree::GenericDomTree, a::BBNumber, b::BBNumber) + a == 0 && return a + b == 0 && return b alevel = domtree.nodes[a].level blevel = domtree.nodes[b].level # W.l.g. assume blevel <= alevel diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index 6f20ca6b20ec8..152fc3be3d1c3 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -1619,6 +1619,7 @@ function try_resolve_finalizer!(ir::IRCode, idx::Int, finalizer_idx::Int, defuse end all(check_defuse, defuse.uses) || return nothing all(check_defuse, defuse.defs) || return nothing + bb_insert_block != 0 || return nothing # verify post-dominator of all uses exists # Check #3 dominates(domtree, finalizer_bb, bb_insert_block) || return nothing diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index c124832030cbd..6d6cd74028594 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -1820,3 +1820,24 @@ function f53521() end end @test code_typed(f53521)[1][2] === Nothing + +# https://github.com/JuliaLang/julia/issues/54596 +# finalized object's uses have no postdominator +let f = (x)->nothing, mi = Base.method_instance(f, (Base.RefValue{Nothing},)), code = Any[ + # Basic Block 1 + Expr(:new, Base.RefValue{Nothing}, nothing) + Expr(:call, Core.finalizer, f, SSAValue(1), true, mi) + GotoIfNot(false, 6) + # Basic Block 2 + Expr(:call, Base.getfield, SSAValue(1), :x) + ReturnNode(SSAValue(4)) + # Basic Block 3 + Expr(:call, Base.getfield, SSAValue(1), :x) + ReturnNode(SSAValue(6)) +] + ir = make_ircode(code; ssavaluetypes=Any[Base.RefValue{Nothing}, Nothing, Any, Nothing, Any, Nothing, Any]) + inlining = Core.Compiler.InliningState(Core.Compiler.NativeInterpreter()) + Core.Compiler.verify_ir(ir) + ir = Core.Compiler.sroa_pass!(ir, inlining) + Core.Compiler.verify_ir(ir) +end