Skip to content

Commit 8827eb3

Browse files
topolarityKristofferC
authored andcommitted
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. (cherry picked from commit cdec4c2)
1 parent 30b8126 commit 8827eb3

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
@@ -1508,10 +1508,20 @@ function finish_current_bb!(compact::IncrementalCompact, active_bb::Int,
15081508
return skipped
15091509
end
15101510

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

15171527
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)
@@ -1523,7 +1533,7 @@ function process_newnode!(compact::IncrementalCompact, new_idx::Int, new_node_en
15231533
compact.result_idx = result_idx
15241534
# If this instruction has reverse affinity and we were at the end of a basic block,
15251535
# finish it now.
1526-
if new_node_info.attach_after && idx == last(bb.stmts)+1 && !attach_after_stmt_after(compact, idx-1)
1536+
if new_node_info.attach_after && idx == last(bb.stmts)+1 && !stmts_awaiting_insertion(compact, idx-1)
15271537
active_bb += 1
15281538
finish_current_bb!(compact, active_bb, old_result_idx)
15291539
end
@@ -1653,7 +1663,7 @@ function iterate_compact(compact::IncrementalCompact)
16531663
compact.result[old_result_idx] = compact.ir.stmts[idx]
16541664
result_idx = process_node!(compact, old_result_idx, compact.ir.stmts[idx], idx, idx, active_bb, true)
16551665
compact.result_idx = result_idx
1656-
if idx == last(bb.stmts) && !attach_after_stmt_after(compact, idx)
1666+
if idx == last(bb.stmts) && !stmts_awaiting_insertion(compact, idx)
16571667
finish_current_bb!(compact, active_bb, old_result_idx)
16581668
active_bb += 1
16591669
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)