Skip to content

Commit 5bf1ca5

Browse files
authored
optimizer: fix #42258, make sure to set ssaflags correctly (#42262)
Essentially, this PR adds missing `ssaflags` deletion of `type_annotate!`. Built on top of #42260.
1 parent f6d693d commit 5bf1ca5

File tree

7 files changed

+47
-11
lines changed

7 files changed

+47
-11
lines changed

base/compiler/optimize.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ mutable struct OptimizationState
8585
if nssavalues isa Int
8686
src.ssavaluetypes = Any[ Any for i = 1:nssavalues ]
8787
else
88-
nssavalues = length(src.ssavaluetypes)
88+
nssavalues = length(src.ssavaluetypes::Vector{Any})
8989
end
9090
nslots = length(src.slotflags)
9191
slottypes = src.slottypes

base/compiler/ssair/legacy.jl

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ function inflate_ir(ci::CodeInfo, sptypes::Vector{Any}, argtypes::Vector{Any})
2929
code[i] = stmt
3030
end
3131
end
32-
ssavaluetypes = ci.ssavaluetypes
3332
nstmts = length(code)
34-
ssavaluetypes = ci.ssavaluetypes isa Vector{Any} ? copy(ci.ssavaluetypes) : Any[ Any for i = 1:(ci.ssavaluetypes::Int) ]
33+
ssavaluetypes = let ssavaluetypes = ci.ssavaluetypes
34+
ssavaluetypes isa Vector{Any} ? copy(ssavaluetypes) : Any[ Any for i = 1:(ssavaluetypes::Int) ]
35+
end
3536
stmts = InstructionStream(code, ssavaluetypes, Any[nothing for i = 1:nstmts], copy(ci.codelocs), copy(ci.ssaflags))
3637
ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable), argtypes, Any[], sptypes)
3738
return ir

base/compiler/ssair/slot2ssa.jl

+5-4
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,14 @@ function strip_trailing_junk!(ci::CodeInfo, code::Vector{Any}, info::Vector{Any}
177177
# Remove `nothing`s at the end, we don't handle them well
178178
# (we expect the last instruction to be a terminator)
179179
ssavaluetypes = ci.ssavaluetypes::Vector{Any}
180+
(; codelocs, ssaflags) = ci
180181
for i = length(code):-1:1
181182
if code[i] !== nothing
182183
resize!(code, i)
183184
resize!(ssavaluetypes, i)
184-
resize!(ci.codelocs, i)
185+
resize!(codelocs, i)
185186
resize!(info, i)
186-
resize!(ci.ssaflags, i)
187+
resize!(ssaflags, i)
187188
break
188189
end
189190
end
@@ -193,9 +194,9 @@ function strip_trailing_junk!(ci::CodeInfo, code::Vector{Any}, info::Vector{Any}
193194
if !isa(term, GotoIfNot) && !isa(term, GotoNode) && !isa(term, ReturnNode)
194195
push!(code, ReturnNode())
195196
push!(ssavaluetypes, Union{})
196-
push!(ci.codelocs, 0)
197+
push!(codelocs, 0)
197198
push!(info, nothing)
198-
push!(ci.ssaflags, IR_FLAG_NULL)
199+
push!(ssaflags, IR_FLAG_NULL)
199200
end
200201
nothing
201202
end

base/compiler/typeinfer.jl

+2
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ function finish(me::InferenceState, interp::AbstractInterpreter)
475475
end
476476
me.result.valid_worlds = me.valid_worlds
477477
me.result.result = me.bestguess
478+
validate_code_in_debug_mode(me.linfo, me.src, "inferred")
478479
nothing
479480
end
480481

@@ -666,6 +667,7 @@ function type_annotate!(sv::InferenceState, run_optimizer::Bool)
666667
deleteat!(ssavaluetypes, i)
667668
deleteat!(src.codelocs, i)
668669
deleteat!(sv.stmt_info, i)
670+
deleteat!(src.ssaflags, i)
669671
nexpr -= 1
670672
changemap[oldidx] = -1
671673
continue

base/compiler/validation.jl

+8-4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const EMPTY_SLOTNAMES = "slotnames field is empty"
4848
const SLOTFLAGS_MISMATCH = "length(slotnames) < length(slotflags)"
4949
const SSAVALUETYPES_MISMATCH = "not all SSAValues in AST have a type in ssavaluetypes"
5050
const SSAVALUETYPES_MISMATCH_UNINFERRED = "uninferred CodeInfo ssavaluetypes field does not equal the number of present SSAValues"
51+
const SSAFLAGS_MISMATCH = "not all SSAValues have a corresponding `ssaflags`"
5152
const NON_TOP_LEVEL_METHOD = "encountered `Expr` head `:method` in non-top-level code (i.e. `nargs` > 0)"
5253
const NON_TOP_LEVEL_GLOBAL = "encountered `Expr` head `:global` in non-top-level code (i.e. `nargs` > 0)"
5354
const SIGNATURE_NARGS_MISMATCH = "method signature does not match number of method arguments"
@@ -183,13 +184,16 @@ function validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo, is_top_
183184
nssavals = length(c.code)
184185
!is_top_level && nslotnames == 0 && push!(errors, InvalidCodeError(EMPTY_SLOTNAMES))
185186
nslotnames < nslotflags && push!(errors, InvalidCodeError(SLOTFLAGS_MISMATCH, (nslotnames, nslotflags)))
186-
if c.inferred
187-
nssavaluetypes = length(c.ssavaluetypes::Vector{Any})
187+
ssavaluetypes = c.ssavaluetypes
188+
if isa(ssavaluetypes, Vector{Any})
189+
nssavaluetypes = length(ssavaluetypes)
188190
nssavaluetypes < nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH, (nssavals, nssavaluetypes)))
189191
else
190-
ssavaluetypes = c.ssavaluetypes::Int
191-
ssavaluetypes != nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH_UNINFERRED, (nssavals, ssavaluetypes)))
192+
nssavaluetypes = ssavaluetypes::Int
193+
nssavaluetypes nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH_UNINFERRED, (nssavals, nssavaluetypes)))
192194
end
195+
nssaflags = length(c.ssaflags)
196+
nssavals nssaflags && push!(errors, InvalidCodeError(SSAFLAGS_MISMATCH, (nssavals, nssaflags)))
193197
return errors
194198
end
195199

test/compiler/ssair.jl

+20
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,23 @@ end
314314
# Issue #41975 - SSA conversion drops type check
315315
f_if_typecheck() = (if nothing; end; unsafe_load(Ptr{Int}(0)))
316316
@test_throws TypeError f_if_typecheck()
317+
318+
@test let # https://github.com/JuliaLang/julia/issues/42258
319+
code = quote
320+
function foo()
321+
a = @noinline rand(rand(0:10))
322+
if isempty(a)
323+
err = BoundsError(a)
324+
throw(err)
325+
return nothing
326+
end
327+
return a
328+
end
329+
code_typed(foo; optimize=true)
330+
331+
code_typed(Core.Compiler.setindex!, (Core.Compiler.UseRef,Core.Compiler.NewSSAValue); optimize=true)
332+
end |> string
333+
cmd = `$(Base.julia_cmd()) -g 2 -e $code`
334+
stderr = IOBuffer()
335+
success(pipeline(Cmd(cmd); stdout=stdout, stderr=stderr)) && isempty(String(take!(stderr)))
336+
end

test/compiler/validation.jl

+8
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ end
105105
@test errors[1].kind === Core.Compiler.SSAVALUETYPES_MISMATCH_UNINFERRED
106106
end
107107

108+
@testset "SSAFLAGS_MISMATCH" begin
109+
c = copy(c0)
110+
empty!(c.ssaflags)
111+
errors = Core.Compiler.validate_code(c)
112+
@test length(errors) == 1
113+
@test errors[1].kind === Core.Compiler.SSAFLAGS_MISMATCH
114+
end
115+
108116
@testset "SIGNATURE_NARGS_MISMATCH" begin
109117
old_sig = mi.def.sig
110118
mi.def.sig = Tuple{1,2}

0 commit comments

Comments
 (0)