From 510d2f97ad2e185f28f04f29d573b8f17dec30a6 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Wed, 15 Sep 2021 19:37:32 +0900 Subject: [PATCH] optimizer: fix #42258, make sure to set `ssaflags` correctly Essentially, this PR adds missing `ssaflags` deletion of `type_annotate!`. Built on top of #42260. --- base/compiler/optimize.jl | 2 +- base/compiler/ssair/legacy.jl | 6 ++++-- base/compiler/ssair/slot2ssa.jl | 9 +++++---- base/compiler/typeinfer.jl | 1 + test/compiler/ssair.jl | 17 +++++++++++++++++ 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index 5acfd22eb995a2..02ee5cdc9ecc11 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -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 diff --git a/base/compiler/ssair/legacy.jl b/base/compiler/ssair/legacy.jl index 4d2bafc2f38d9b..e393b2bff049c6 100644 --- a/base/compiler/ssair/legacy.jl +++ b/base/compiler/ssair/legacy.jl @@ -29,9 +29,11 @@ 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 diff --git a/base/compiler/ssair/slot2ssa.jl b/base/compiler/ssair/slot2ssa.jl index 656df9b17e4c4a..846ebde4c0bb11 100644 --- a/base/compiler/ssair/slot2ssa.jl +++ b/base/compiler/ssair/slot2ssa.jl @@ -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 @@ -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 diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index c3b7c4dc3a3d0d..9d12c890d6be6c 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -666,6 +666,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 diff --git a/test/compiler/ssair.jl b/test/compiler/ssair.jl index 17a0753eddc640..e716730b86a390 100644 --- a/test/compiler/ssair.jl +++ b/test/compiler/ssair.jl @@ -314,3 +314,20 @@ 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() + +let # https://github.com/JuliaLang/julia/issues/42258 + # XXX this test case is not so robust against the future changes within `Core.Compiler` + ci, = only(code_typed(Core.Compiler.setindex!, (Core.Compiler.UseRef,Core.Compiler.NewSSAValue); optimize=true)) + idx = filter(1:length(ci.code)) do i + stmt = ci.code[i] + if Meta.isexpr(stmt, :call) + t = Core.Compiler.argextype(stmt.args[1], ci, Any[]) + ft = Core.Compiler.widenconst(t) + return ft === typeof(BoundsError) || ft === typeof(throw) + end + return false + end + @test all(ci.ssaflags[idx]) do flag + flag & Core.Compiler.IR_FLAG_THROW_BLOCK ≠ 0 + end +end