Skip to content

Commit d3268f8

Browse files
topolarityDrvi
authored andcommitted
Fix condition for unreachable code in IRCode conversion (JuliaLang#53512)
This is a partial back-port of JuliaLang#50924, where we discovered that the optimizer would ignore: 1. must-throw `%XX = SlotNumber(_)` statements 2. must-throw `goto #bb if not %x` statements This is mostly harmless, except that in the case of (1) we can accidentally fall through the statically deleted (`Const()`-wrapped) code from inference and end up observing a control-flow edge that never existed. If the spurious edge is to a catch block, then the edge is invalid semantically and breaks our SSA conversion. This one-line change fixes (1) but not (2), which is enough for IR validity. Resolves part of JuliaLang#53366. (cherry picked from commit 035d17a)
1 parent a0183a1 commit d3268f8

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

base/compiler/optimize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ function convert_to_ircode(ci::CodeInfo, sv::OptimizationState)
561561
idx += 1
562562
prevloc = codeloc
563563
end
564-
if code[idx] isa Expr && ssavaluetypes[idx] === Union{}
564+
if ssavaluetypes[idx] === Union{} && code[idx] !== nothing && !(code[idx] isa Core.Const)
565565
if !(idx < length(code) && isa(code[idx + 1], ReturnNode) && !isdefined((code[idx + 1]::ReturnNode), :val))
566566
# insert unreachable in the same basic block after the current instruction (splitting it)
567567
insert!(code, idx + 1, ReturnNode())

test/compiler/inference.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5161,3 +5161,27 @@ let x = 1, _Any = Any
51615161
foo27031() = bar27031((x, 1.0), Val{_Any})
51625162
@test foo27031() == "OK"
51635163
end
5164+
5165+
# Issue #53366
5166+
#
5167+
# FIXME: This test is quite brittle, since it relies on lowering making a particular
5168+
# (and unnecessary) decision to embed a `SlotNumber` in statement position.
5169+
#
5170+
# This should be re-written to have the bad IR directly, then run type inference +
5171+
# SSA conversion. It should also avoid running `compact!` afterward, since that can
5172+
# mask bugs by cleaning up unused ϕ nodes that should never have existed.
5173+
function issue53366(sc::Threads.Condition)
5174+
@lock sc begin
5175+
try
5176+
if Core.Compiler.inferencebarrier(true)
5177+
return nothing
5178+
end
5179+
return nothing
5180+
finally
5181+
end
5182+
end
5183+
end
5184+
5185+
let (ir, rt) = only(Base.code_ircode(issue53366, (Threads.Condition,)))
5186+
Core.Compiler.verify_ir(ir)
5187+
end

0 commit comments

Comments
 (0)