Skip to content

Commit

Permalink
fix #44763, implement missing effects propagation from abstract_invoke
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Mar 27, 2022
1 parent 9d31f6a commit da6b061
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 17 deletions.
29 changes: 12 additions & 17 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1503,25 +1503,26 @@ end
function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, sv::InferenceState)
ft′ = argtype_by_index(argtypes, 2)
ft = widenconst(ft′)
ft === Bottom && return CallMeta(Bottom, false)
ft === Bottom && return CallMeta(Bottom, false), EFFECTS_THROW
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3))
types === Bottom && return CallMeta(Bottom, false)
isexact || return CallMeta(Any, false)
types === Bottom && return CallMeta(Bottom, false), EFFECTS_THROW
isexact || return CallMeta(Any, false), Effects()
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
nargtype = typeintersect(types, argtype)
nargtype === Bottom && return CallMeta(Bottom, false)
nargtype isa DataType || return CallMeta(Any, false) # other cases are not implemented below
isdispatchelem(ft) || return CallMeta(Any, false) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
nargtype === Bottom && return CallMeta(Bottom, false), EFFECTS_THROW
nargtype isa DataType || return CallMeta(Any, false), Effects() # other cases are not implemented below
isdispatchelem(ft) || return CallMeta(Any, false), Effects() # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
ft = ft::DataType
types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
nargtype = Tuple{ft, nargtype.parameters...}
argtype = Tuple{ft, argtype.parameters...}
match, valid_worlds, overlayed = findsup(types, method_table(interp))
match === nothing && return CallMeta(Any, false)
match === nothing && return CallMeta(Any, false), Effects()
update_valid_age!(sv, valid_worlds)
method = match.method
(ti, env::SimpleVector) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
(; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv)
effects = result.edge_effects
edge !== nothing && add_backedge!(edge::MethodInstance, sv)
match = MethodMatch(ti, env, method, argtype <: method.sig)
res = nothing
Expand All @@ -1539,10 +1540,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
const_result = nothing
if const_call_result !== nothing
if const_call_result.rt rt
(; rt, const_result) = const_call_result
(; rt, effects, const_result) = const_call_result
end
end
return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result))
return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result)), effects
end

function invoke_rewrite(xs::Vector{Any})
Expand All @@ -1563,14 +1564,8 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
if f === _apply_iterate
return abstract_apply(interp, argtypes, sv, max_methods)
elseif f === invoke
call = abstract_invoke(interp, arginfo, sv)
if call.info === false
if call.rt === Bottom
tristate_merge!(sv, Effects(EFFECTS_TOTAL; nothrow=ALWAYS_FALSE))
else
tristate_merge!(sv, Effects())
end
end
call, effects = abstract_invoke(interp, arginfo, sv)
tristate_merge!(sv, effects)
return call
elseif f === modifyfield!
tristate_merge!(sv, Effects()) # TODO
Expand Down
1 change: 1 addition & 0 deletions base/compiler/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function Effects(
end

const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, false)
const EFFECTS_THROW = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_FALSE, ALWAYS_TRUE, false)
const EFFECTS_UNKNOWN = Effects(TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, true)

function Effects(e::Effects = EFFECTS_UNKNOWN;
Expand Down
9 changes: 9 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4080,3 +4080,12 @@ end
Base.Experimental.@force_compile
Core.Compiler.return_type(+, NTuple{2, Rational})
end == Rational

# https://github.com/JuliaLang/julia/issues/44763
global x44763::Int = 0
increase_x44763!(n) = (global x44763; x44763 += n)
invoke44763(x) = Base.@invoke increase_x44763!(x)
@test Base.return_types() do
invoke44763(42)
end |> only === Int
@test x44763 == 0

0 comments on commit da6b061

Please sign in to comment.