Skip to content

Commit 64f8634

Browse files
committed
Handle no-postdominator case in finalizer pass
This pass was assuming that the post-dominator of all finalizer uses exists as a real BB in the CFG.
1 parent 456ed21 commit 64f8634

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

base/compiler/ssair/domtree.jl

+2
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,8 @@ end
644644
Compute the nearest common (post-)dominator of `a` and `b`.
645645
"""
646646
function nearest_common_dominator(domtree::GenericDomTree, a::BBNumber, b::BBNumber)
647+
a == 0 && return a
648+
b == 0 && return b
647649
alevel = domtree.nodes[a].level
648650
blevel = domtree.nodes[b].level
649651
# W.l.g. assume blevel <= alevel

base/compiler/ssair/passes.jl

+1
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,7 @@ function try_resolve_finalizer!(ir::IRCode, idx::Int, finalizer_idx::Int, defuse
12941294
end
12951295
all(check_defuse, defuse.uses) || return nothing
12961296
all(check_defuse, defuse.defs) || return nothing
1297+
bb_insert_block != 0 || return nothing # verify post-dominator of all uses exists
12971298

12981299
# Check #3
12991300
dominates(domtree, finalizer_bb, bb_insert_block) || return nothing

test/compiler/irpasses.jl

+21
Original file line numberDiff line numberDiff line change
@@ -1355,3 +1355,24 @@ let src = code_typed1(mut50285, Tuple{Bool, Int, Float64})
13551355
@test count(isnew, src.code) == 0
13561356
@test count(iscall((src, typeassert)), src.code) == 0
13571357
end
1358+
1359+
# https://github.com/JuliaLang/julia/issues/54596
1360+
# finalized object's uses have no postdominator
1361+
let f = (x)->nothing, mi = only(Base.method_instances(f, (Base.RefValue{Nothing},), Base.get_world_counter())), code = Any[
1362+
# Basic Block 1
1363+
Expr(:new, Base.RefValue{Nothing}, nothing)
1364+
Expr(:call, Core.finalizer, f, SSAValue(1), true, mi)
1365+
GotoIfNot(false, 6)
1366+
# Basic Block 2
1367+
Expr(:call, Base.getfield, SSAValue(1), :x)
1368+
ReturnNode(SSAValue(4))
1369+
# Basic Block 3
1370+
Expr(:call, Base.getfield, SSAValue(1), :x)
1371+
ReturnNode(SSAValue(6))
1372+
]
1373+
ir = make_ircode(code; ssavaluetypes=Any[Base.RefValue{Nothing}, Nothing, Any, Nothing, Any, Nothing, Any])
1374+
inlining = Core.Compiler.InliningState(Core.Compiler.NativeInterpreter())
1375+
Core.Compiler.verify_ir(ir)
1376+
ir = Core.Compiler.sroa_pass!(ir, inlining)
1377+
Core.Compiler.verify_ir(ir)
1378+
end

0 commit comments

Comments
 (0)