Skip to content

Commit ace08d8

Browse files
committed
Fix bug when inlining pending nodes
While working on IR, we give pending nodes SSA ids after the main body of the function, and then we drop them in place during compaction. Inlining was using thse IDs to try to determine which basic block we're currently inlining into, but for pending blocks it was looking at the raw ID rather than the insertion position, corrupting the CFG. Fixes #37555 Fixes #37182
1 parent 8e3f298 commit ace08d8

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

base/compiler/ssair/inlining.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ function inline_into_block!(state::CFGInliningState, block::Int)
112112
return
113113
end
114114

115-
function cfg_inline_item!(idx::Int, spec::ResolvedInliningSpec, state::CFGInliningState, from_unionsplit::Bool=false)
115+
function cfg_inline_item!(ir::IRCode, idx::Int, spec::ResolvedInliningSpec, state::CFGInliningState, from_unionsplit::Bool=false)
116116
inlinee_cfg = spec.ir.cfg
117117
# Figure out if we need to split the BB
118118
need_split_before = false
119119
need_split = true
120-
block = block_for_inst(state.cfg, idx)
120+
block = block_for_inst(ir, idx)
121121
inline_into_block!(state, block)
122122

123123
if !isempty(inlinee_cfg.blocks[1].preds)
@@ -206,8 +206,8 @@ function cfg_inline_item!(idx::Int, spec::ResolvedInliningSpec, state::CFGInlini
206206
end
207207
end
208208

209-
function cfg_inline_unionsplit!(idx::Int, item::UnionSplit, state::CFGInliningState)
210-
block = block_for_inst(state.cfg, idx)
209+
function cfg_inline_unionsplit!(ir::IRCode, idx::Int, item::UnionSplit, state::CFGInliningState)
210+
block = block_for_inst(ir, idx)
211211
inline_into_block!(state, block)
212212
from_bbs = Int[]
213213
delete!(state.split_targets, length(state.new_cfg_blocks))
@@ -223,7 +223,7 @@ function cfg_inline_unionsplit!(idx::Int, item::UnionSplit, state::CFGInliningSt
223223
if isa(case, InliningTodo)
224224
spec = case.spec::ResolvedInliningSpec
225225
if !spec.linear_inline_eligible
226-
cfg_inline_item!(idx, spec, state, true)
226+
cfg_inline_item!(ir, idx, spec, state, true)
227227
end
228228
end
229229
bb = length(state.new_cfg_blocks)
@@ -501,13 +501,13 @@ function batch_inline!(todo::Vector{Pair{Int, Any}}, ir::IRCode, linetable::Vect
501501
state = CFGInliningState(ir)
502502
for (idx, item) in todo
503503
if isa(item, UnionSplit)
504-
cfg_inline_unionsplit!(idx, item::UnionSplit, state)
504+
cfg_inline_unionsplit!(ir, idx, item::UnionSplit, state)
505505
else
506506
item = item::InliningTodo
507507
spec = item.spec::ResolvedInliningSpec
508508
# A linear inline does not modify the CFG
509509
spec.linear_inline_eligible && continue
510-
cfg_inline_item!(idx, spec, state, false)
510+
cfg_inline_item!(ir, idx, spec, state, false)
511511
end
512512
end
513513
finish_cfg_inline!(state)

base/compiler/ssair/ir.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,13 @@ struct IRCode
272272
copy(ir.linetable), copy(ir.cfg), copy(ir.new_nodes), copy(ir.meta))
273273
end
274274

275+
function block_for_inst(ir::IRCode, inst::Int)
276+
if inst > length(ir.stmts)
277+
inst = ir.new_nodes.info[inst - length(ir.stmts)].pos
278+
end
279+
block_for_inst(ir.cfg, inst)
280+
end
281+
275282
function getindex(x::IRCode, s::SSAValue)
276283
if s.id <= length(x.stmts)
277284
return x.stmts[s.id][:inst]

test/compiler/inline.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,11 @@ let ci = code_typed(f_29115, Tuple{Pair{Int64, Int64}})[1].first
307307
@test length(ci.code) == 4 && isexpr(ci.code[1], :call) &&
308308
ci.code[end-1].args[1] === GlobalRef(Core, :tuple)
309309
end
310+
311+
# Issue #37182 & #37555 - Inlining of pending nodes
312+
function f37555(x::Int; kwargs...)
313+
@assert x < 10
314+
+(x, kwargs...)
315+
end
316+
@test f37555(1) == 1
317+

0 commit comments

Comments
 (0)