Skip to content

Commit 5e7b6dd

Browse files
authored
inference: look for :terminate_globally override in backedge termination check (#44106)
Now we can "fix" #41694: ```julia Base.@assume_effects :terminates_globally function issue41694(x) res = 1 1 < x < 20 || throw("bad") while x > 1 res *= x x -= 1 end return res end @test fully_eliminated() do issue41694(2) end ```
1 parent 2842fe1 commit 5e7b6dd

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

base/compiler/abstractinterpretation.jl

+6-3
Original file line numberDiff line numberDiff line change
@@ -1878,7 +1878,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e),
18781878
effects.consistent ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
18791879
effects.effect_free ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
18801880
effects.nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1881-
effects.terminates ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
1881+
effects.terminates_globally ? ALWAYS_TRUE : TRISTATE_UNKNOWN,
18821882
))
18831883
else
18841884
tristate_merge!(sv, Effects())
@@ -2052,8 +2052,11 @@ end
20522052
function handle_control_backedge!(frame::InferenceState, from::Int, to::Int)
20532053
if from > to
20542054
def = frame.linfo.def
2055-
if isa(def, Method) && decode_effects_override(def.purity).terminates_locally
2056-
return nothing
2055+
if isa(def, Method)
2056+
effects = decode_effects_override(def.purity)
2057+
if effects.terminates_globally || effects.terminates_locally
2058+
return nothing
2059+
end
20572060
end
20582061
tristate_merge!(frame, Effects(EFFECTS_TOTAL, terminates=TRISTATE_UNKNOWN))
20592062
end

base/compiler/types.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct EffectsOverride
8989
consistent::Bool
9090
effect_free::Bool
9191
nothrow::Bool
92-
terminates::Bool
92+
terminates_globally::Bool
9393
terminates_locally::Bool
9494
end
9595

@@ -98,7 +98,7 @@ function encode_effects_override(eo::EffectsOverride)
9898
eo.consistent && (e |= 0x01)
9999
eo.effect_free && (e |= 0x02)
100100
eo.nothrow && (e |= 0x04)
101-
eo.terminates && (e |= 0x08)
101+
eo.terminates_globally && (e |= 0x08)
102102
eo.terminates_locally && (e |= 0x10)
103103
e
104104
end

test/compiler/inline.jl

+14
Original file line numberDiff line numberDiff line change
@@ -1055,3 +1055,17 @@ function f_call_invoke_callback(f::FCallback)
10551055
return nothing
10561056
end
10571057
@test !fully_eliminated(f_call_invoke_callback, Tuple{FCallback})
1058+
1059+
# https://github.com/JuliaLang/julia/issues/41694
1060+
Base.@assume_effects :terminates_globally function issue41694(x)
1061+
res = 1
1062+
1 < x < 20 || throw("bad")
1063+
while x > 1
1064+
res *= x
1065+
x -= 1
1066+
end
1067+
return res
1068+
end
1069+
@test fully_eliminated() do
1070+
issue41694(2)
1071+
end

0 commit comments

Comments
 (0)