Skip to content

Commit

Permalink
optimizer: fix #42258, make sure to set ssaflags correctly (#42262)
Browse files Browse the repository at this point in the history
Essentially, this PR adds missing `ssaflags` deletion of `type_annotate!`.
Built on top of #42260.
  • Loading branch information
aviatesk authored and KristofferC committed Sep 28, 2021
1 parent 8947924 commit 1d1c935
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 11 deletions.
2 changes: 1 addition & 1 deletion base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ mutable struct OptimizationState
if nssavalues isa Int
src.ssavaluetypes = Any[ Any for i = 1:nssavalues ]
else
nssavalues = length(src.ssavaluetypes)
nssavalues = length(src.ssavaluetypes::Vector{Any})
end
nslots = length(src.slotflags)
slottypes = src.slottypes
Expand Down
5 changes: 3 additions & 2 deletions base/compiler/ssair/legacy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ function inflate_ir(ci::CodeInfo, sptypes::Vector{Any}, argtypes::Vector{Any})
code[i] = stmt
end
end
ssavaluetypes = ci.ssavaluetypes
nstmts = length(code)
ssavaluetypes = ci.ssavaluetypes isa Vector{Any} ? copy(ci.ssavaluetypes) : Any[ Any for i = 1:(ci.ssavaluetypes::Int) ]
ssavaluetypes = let ssavaluetypes = ci.ssavaluetypes
ssavaluetypes isa Vector{Any} ? copy(ssavaluetypes) : Any[ Any for i = 1:(ssavaluetypes::Int) ]
end
stmts = InstructionStream(code, ssavaluetypes, Any[nothing for i = 1:nstmts], copy(ci.codelocs), copy(ci.ssaflags))
ir = IRCode(stmts, cfg, collect(LineInfoNode, ci.linetable), argtypes, Any[], sptypes)
return ir
Expand Down
9 changes: 5 additions & 4 deletions base/compiler/ssair/slot2ssa.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,14 @@ function strip_trailing_junk!(ci::CodeInfo, code::Vector{Any}, info::Vector{Any}
# Remove `nothing`s at the end, we don't handle them well
# (we expect the last instruction to be a terminator)
ssavaluetypes = ci.ssavaluetypes::Vector{Any}
(; codelocs, ssaflags) = ci
for i = length(code):-1:1
if code[i] !== nothing
resize!(code, i)
resize!(ssavaluetypes, i)
resize!(ci.codelocs, i)
resize!(codelocs, i)
resize!(info, i)
resize!(ci.ssaflags, i)
resize!(ssaflags, i)
break
end
end
Expand All @@ -193,9 +194,9 @@ function strip_trailing_junk!(ci::CodeInfo, code::Vector{Any}, info::Vector{Any}
if !isa(term, GotoIfNot) && !isa(term, GotoNode) && !isa(term, ReturnNode)
push!(code, ReturnNode())
push!(ssavaluetypes, Union{})
push!(ci.codelocs, 0)
push!(codelocs, 0)
push!(info, nothing)
push!(ci.ssaflags, IR_FLAG_NULL)
push!(ssaflags, IR_FLAG_NULL)
end
nothing
end
Expand Down
2 changes: 2 additions & 0 deletions base/compiler/typeinfer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ function finish(me::InferenceState, interp::AbstractInterpreter)
end
me.result.valid_worlds = me.valid_worlds
me.result.result = me.bestguess
validate_code_in_debug_mode(me.linfo, me.src, "inferred")
nothing
end

Expand Down Expand Up @@ -666,6 +667,7 @@ function type_annotate!(sv::InferenceState, run_optimizer::Bool)
deleteat!(ssavaluetypes, i)
deleteat!(src.codelocs, i)
deleteat!(sv.stmt_info, i)
deleteat!(src.ssaflags, i)
nexpr -= 1
changemap[oldidx] = -1
continue
Expand Down
12 changes: 8 additions & 4 deletions base/compiler/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const EMPTY_SLOTNAMES = "slotnames field is empty"
const SLOTFLAGS_MISMATCH = "length(slotnames) < length(slotflags)"
const SSAVALUETYPES_MISMATCH = "not all SSAValues in AST have a type in ssavaluetypes"
const SSAVALUETYPES_MISMATCH_UNINFERRED = "uninferred CodeInfo ssavaluetypes field does not equal the number of present SSAValues"
const SSAFLAGS_MISMATCH = "not all SSAValues have a corresponding `ssaflags`"
const NON_TOP_LEVEL_METHOD = "encountered `Expr` head `:method` in non-top-level code (i.e. `nargs` > 0)"
const NON_TOP_LEVEL_GLOBAL = "encountered `Expr` head `:global` in non-top-level code (i.e. `nargs` > 0)"
const SIGNATURE_NARGS_MISMATCH = "method signature does not match number of method arguments"
Expand Down Expand Up @@ -183,13 +184,16 @@ function validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo, is_top_
nssavals = length(c.code)
!is_top_level && nslotnames == 0 && push!(errors, InvalidCodeError(EMPTY_SLOTNAMES))
nslotnames < nslotflags && push!(errors, InvalidCodeError(SLOTFLAGS_MISMATCH, (nslotnames, nslotflags)))
if c.inferred
nssavaluetypes = length(c.ssavaluetypes::Vector{Any})
ssavaluetypes = c.ssavaluetypes
if isa(ssavaluetypes, Vector{Any})
nssavaluetypes = length(ssavaluetypes)
nssavaluetypes < nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH, (nssavals, nssavaluetypes)))
else
ssavaluetypes = c.ssavaluetypes::Int
ssavaluetypes != nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH_UNINFERRED, (nssavals, ssavaluetypes)))
nssavaluetypes = ssavaluetypes::Int
nssavaluetypes nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH_UNINFERRED, (nssavals, nssavaluetypes)))
end
nssaflags = length(c.ssaflags)
nssavals nssaflags && push!(errors, InvalidCodeError(SSAFLAGS_MISMATCH, (nssavals, nssaflags)))
return errors
end

Expand Down
20 changes: 20 additions & 0 deletions test/compiler/ssair.jl
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,23 @@ end
# Issue #41975 - SSA conversion drops type check
f_if_typecheck() = (if nothing; end; unsafe_load(Ptr{Int}(0)))
@test_throws TypeError f_if_typecheck()

@test let # https://github.com/JuliaLang/julia/issues/42258
code = quote
function foo()
a = @noinline rand(rand(0:10))
if isempty(a)
err = BoundsError(a)
throw(err)
return nothing
end
return a
end
code_typed(foo; optimize=true)

code_typed(Core.Compiler.setindex!, (Core.Compiler.UseRef,Core.Compiler.NewSSAValue); optimize=true)
end |> string
cmd = `$(Base.julia_cmd()) -g 2 -e $code`
stderr = IOBuffer()
success(pipeline(Cmd(cmd); stdout=stdout, stderr=stderr)) && isempty(String(take!(stderr)))
end
8 changes: 8 additions & 0 deletions test/compiler/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ end
@test errors[1].kind === Core.Compiler.SSAVALUETYPES_MISMATCH_UNINFERRED
end

@testset "SSAFLAGS_MISMATCH" begin
c = copy(c0)
empty!(c.ssaflags)
errors = Core.Compiler.validate_code(c)
@test length(errors) == 1
@test errors[1].kind === Core.Compiler.SSAFLAGS_MISMATCH
end

@testset "SIGNATURE_NARGS_MISMATCH" begin
old_sig = mi.def.sig
mi.def.sig = Tuple{1,2}
Expand Down

0 comments on commit 1d1c935

Please sign in to comment.