Skip to content

Commit c4a53a8

Browse files
aviateskKristofferC
authored andcommitted
inference: implement missing effects propagation from abstract_invoke (#44764)
Fix #44763 (cherry picked from commit 9d35089)
1 parent f560674 commit c4a53a8

File tree

3 files changed

+22
-17
lines changed

3 files changed

+22
-17
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,25 +1490,26 @@ end
14901490
function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgInfo, sv::InferenceState)
14911491
ft′ = argtype_by_index(argtypes, 2)
14921492
ft = widenconst(ft′)
1493-
ft === Bottom && return CallMeta(Bottom, false)
1493+
ft === Bottom && return CallMeta(Bottom, false), EFFECTS_THROWN
14941494
(types, isexact, isconcrete, istype) = instanceof_tfunc(argtype_by_index(argtypes, 3))
1495-
types === Bottom && return CallMeta(Bottom, false)
1496-
isexact || return CallMeta(Any, false)
1495+
types === Bottom && return CallMeta(Bottom, false), EFFECTS_THROWN
1496+
isexact || return CallMeta(Any, false), Effects()
14971497
argtype = argtypes_to_type(argtype_tail(argtypes, 4))
14981498
nargtype = typeintersect(types, argtype)
1499-
nargtype === Bottom && return CallMeta(Bottom, false)
1500-
nargtype isa DataType || return CallMeta(Any, false) # other cases are not implemented below
1501-
isdispatchelem(ft) || return CallMeta(Any, false) # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
1499+
nargtype === Bottom && return CallMeta(Bottom, false), EFFECTS_THROWN
1500+
nargtype isa DataType || return CallMeta(Any, false), Effects() # other cases are not implemented below
1501+
isdispatchelem(ft) || return CallMeta(Any, false), Effects() # check that we might not have a subtype of `ft` at runtime, before doing supertype lookup below
15021502
ft = ft::DataType
15031503
types = rewrap_unionall(Tuple{ft, unwrap_unionall(types).parameters...}, types)::Type
15041504
nargtype = Tuple{ft, nargtype.parameters...}
15051505
argtype = Tuple{ft, argtype.parameters...}
15061506
match, valid_worlds, overlayed = findsup(types, method_table(interp))
1507-
match === nothing && return CallMeta(Any, false)
1507+
match === nothing && return CallMeta(Any, false), Effects()
15081508
update_valid_age!(sv, valid_worlds)
15091509
method = match.method
15101510
(ti, env::SimpleVector) = ccall(:jl_type_intersection_with_env, Any, (Any, Any), nargtype, method.sig)::SimpleVector
15111511
(; rt, edge) = result = abstract_call_method(interp, method, ti, env, false, sv)
1512+
effects = result.edge_effects
15121513
edge !== nothing && add_backedge!(edge::MethodInstance, sv)
15131514
match = MethodMatch(ti, env, method, argtype <: method.sig)
15141515
res = nothing
@@ -1526,10 +1527,10 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn
15261527
const_result = nothing
15271528
if const_call_result !== nothing
15281529
if const_call_result.rt rt
1529-
(; rt, const_result) = const_call_result
1530+
(; rt, effects, const_result) = const_call_result
15301531
end
15311532
end
1532-
return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result))
1533+
return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result)), effects
15331534
end
15341535

15351536
function invoke_rewrite(xs::Vector{Any})
@@ -1550,14 +1551,8 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
15501551
if f === _apply_iterate
15511552
return abstract_apply(interp, argtypes, sv, max_methods)
15521553
elseif f === invoke
1553-
call = abstract_invoke(interp, arginfo, sv)
1554-
if call.info === false
1555-
if call.rt === Bottom
1556-
tristate_merge!(sv, Effects(EFFECTS_TOTAL; nothrow=ALWAYS_FALSE))
1557-
else
1558-
tristate_merge!(sv, Effects())
1559-
end
1560-
end
1554+
call, effects = abstract_invoke(interp, arginfo, sv)
1555+
tristate_merge!(sv, effects)
15611556
return call
15621557
elseif f === modifyfield!
15631558
tristate_merge!(sv, Effects()) # TODO

base/compiler/types.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function Effects(
5959
end
6060

6161
const EFFECTS_TOTAL = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_TRUE, false)
62+
const EFFECTS_THROWN = Effects(ALWAYS_TRUE, ALWAYS_TRUE, ALWAYS_FALSE, ALWAYS_TRUE, false)
6263
const EFFECTS_UNKNOWN = Effects(TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, TRISTATE_UNKNOWN, true)
6364

6465
function Effects(e::Effects = EFFECTS_UNKNOWN;

test/compiler/inference.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4055,3 +4055,12 @@ end
40554055
@test Tuple{} <: code_typed(f_boundscheck_elim, Tuple{Int})[1][2]
40564056

40574057
@test !Core.Compiler.builtin_nothrow(Core.get_binding_type, Any[Rational{Int}, Core.Const(:foo)], Any)
4058+
4059+
# https://github.com/JuliaLang/julia/issues/44763
4060+
global x44763::Int = 0
4061+
increase_x44763!(n) = (global x44763; x44763 += n)
4062+
invoke44763(x) = Base.@invoke increase_x44763!(x)
4063+
@test Base.return_types() do
4064+
invoke44763(42)
4065+
end |> only === Int
4066+
@test x44763 == 0

0 commit comments

Comments
 (0)