Skip to content

Commit cdec4c2

Browse files
authored
ssair: Correctly handle stmt insertion at end of basic block (#50528)
In the presence of `attach_after` insertions, we have to be careful to extend the basic block to include everything up to the last insertion. We were accounting for "new" nodes (before the compaction point), but not "pending" nodes (after the compaction point). Fixes #50379.
1 parent 9091cb0 commit cdec4c2

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

base/compiler/ssair/ir.jl

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,10 +1511,20 @@ function finish_current_bb!(compact::IncrementalCompact, active_bb::Int,
15111511
return skipped
15121512
end
15131513

1514-
function attach_after_stmt_after(compact::IncrementalCompact, idx::Int)
1515-
compact.new_nodes_idx > length(compact.perm) && return false
1516-
entry = compact.ir.new_nodes.info[compact.perm[compact.new_nodes_idx]]
1517-
return entry.pos == idx && entry.attach_after
1514+
"""
1515+
stmts_awaiting_insertion(compact::IncrementalCompact, idx::Int)
1516+
1517+
Returns true if there are new/pending instructions enqueued for insertion into
1518+
`compact` on any instruction in the range `1:idx`. Otherwise, returns false.
1519+
"""
1520+
function stmts_awaiting_insertion(compact::IncrementalCompact, idx::Int)
1521+
1522+
new_node_waiting = compact.new_nodes_idx <= length(compact.perm) &&
1523+
compact.ir.new_nodes.info[compact.perm[compact.new_nodes_idx]].pos <= idx
1524+
pending_node_waiting = !isempty(compact.pending_perm) &&
1525+
compact.pending_nodes.info[compact.pending_perm[1]].pos <= idx
1526+
1527+
return new_node_waiting || pending_node_waiting
15181528
end
15191529

15201530
function process_newnode!(compact::IncrementalCompact, new_idx::Int, new_node_entry::Instruction, new_node_info::NewNodeInfo, idx::Int, active_bb::Int, do_rename_ssa::Bool)
@@ -1526,7 +1536,7 @@ function process_newnode!(compact::IncrementalCompact, new_idx::Int, new_node_en
15261536
compact.result_idx = result_idx
15271537
# If this instruction has reverse affinity and we were at the end of a basic block,
15281538
# finish it now.
1529-
if new_node_info.attach_after && idx == last(bb.stmts)+1 && !attach_after_stmt_after(compact, idx-1)
1539+
if new_node_info.attach_after && idx == last(bb.stmts)+1 && !stmts_awaiting_insertion(compact, idx-1)
15301540
active_bb += 1
15311541
finish_current_bb!(compact, active_bb, old_result_idx)
15321542
end
@@ -1656,7 +1666,7 @@ function iterate_compact(compact::IncrementalCompact)
16561666
compact.result[old_result_idx] = compact.ir.stmts[idx]
16571667
result_idx = process_node!(compact, old_result_idx, compact.ir.stmts[idx], idx, idx, active_bb, true)
16581668
compact.result_idx = result_idx
1659-
if idx == last(bb.stmts) && !attach_after_stmt_after(compact, idx)
1669+
if idx == last(bb.stmts) && !stmts_awaiting_insertion(compact, idx)
16601670
finish_current_bb!(compact, active_bb, old_result_idx)
16611671
active_bb += 1
16621672
end

test/compiler/ssair.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,33 @@ let ir = Base.code_ircode((Int,Int); optimize_until="inlining") do a, b
566566
@test call2.args[2] === SSAValue(2)
567567
end
568568

569+
# Issue #50379 - insert_node!(::IncrementalCompact, ...) at end of basic block
570+
let ci = make_ci([
571+
# block 1
572+
#= %1: =# Core.Compiler.GotoIfNot(Expr(:boundscheck), 3),
573+
# block 2
574+
#= %2: =# Expr(:call, println, Argument(1)),
575+
# block 3
576+
#= %3: =# Core.PhiNode(),
577+
#= %4: =# Core.Compiler.ReturnNode(),
578+
])
579+
ir = Core.Compiler.inflate_ir(ci)
580+
581+
# Insert another call at end of "block 2"
582+
compact = Core.Compiler.IncrementalCompact(ir)
583+
new_inst = NewInstruction(Expr(:call, println, Argument(1)), Nothing)
584+
insert_node!(compact, SSAValue(2), new_inst, #= attach_after =# true)
585+
586+
# Complete iteration
587+
x = Core.Compiler.iterate(compact)
588+
while x !== nothing
589+
x = Core.Compiler.iterate(compact, x[2])
590+
end
591+
ir = Core.Compiler.complete(compact)
592+
593+
@test Core.Compiler.verify_ir(ir) === nothing
594+
end
595+
569596
# insert_node! with new instruction with flag computed
570597
let ir = Base.code_ircode((Int,Int); optimize_until="inlining") do a, b
571598
a^b

0 commit comments

Comments
 (0)