From 5e7b6dd090791ca545897d9625a82cae34c116b1 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Mon, 14 Feb 2022 10:06:55 +0900 Subject: [PATCH] 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 ``` --- base/compiler/abstractinterpretation.jl | 9 ++++++--- base/compiler/types.jl | 4 ++-- test/compiler/inline.jl | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 219208ab3b80d..342b7e7d5e13a 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1878,7 +1878,7 @@ function abstract_eval_statement(interp::AbstractInterpreter, @nospecialize(e), effects.consistent ? ALWAYS_TRUE : TRISTATE_UNKNOWN, effects.effect_free ? ALWAYS_TRUE : TRISTATE_UNKNOWN, effects.nothrow ? ALWAYS_TRUE : TRISTATE_UNKNOWN, - effects.terminates ? ALWAYS_TRUE : TRISTATE_UNKNOWN, + effects.terminates_globally ? ALWAYS_TRUE : TRISTATE_UNKNOWN, )) else tristate_merge!(sv, Effects()) @@ -2052,8 +2052,11 @@ end function handle_control_backedge!(frame::InferenceState, from::Int, to::Int) if from > to def = frame.linfo.def - if isa(def, Method) && decode_effects_override(def.purity).terminates_locally - return nothing + if isa(def, Method) + effects = decode_effects_override(def.purity) + if effects.terminates_globally || effects.terminates_locally + return nothing + end end tristate_merge!(frame, Effects(EFFECTS_TOTAL, terminates=TRISTATE_UNKNOWN)) end diff --git a/base/compiler/types.jl b/base/compiler/types.jl index cebb560a2010b..3b19b509f11bf 100644 --- a/base/compiler/types.jl +++ b/base/compiler/types.jl @@ -89,7 +89,7 @@ struct EffectsOverride consistent::Bool effect_free::Bool nothrow::Bool - terminates::Bool + terminates_globally::Bool terminates_locally::Bool end @@ -98,7 +98,7 @@ function encode_effects_override(eo::EffectsOverride) eo.consistent && (e |= 0x01) eo.effect_free && (e |= 0x02) eo.nothrow && (e |= 0x04) - eo.terminates && (e |= 0x08) + eo.terminates_globally && (e |= 0x08) eo.terminates_locally && (e |= 0x10) e end diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 8a3d88fb9d1e0..9347acc83f13f 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -1055,3 +1055,17 @@ function f_call_invoke_callback(f::FCallback) return nothing end @test !fully_eliminated(f_call_invoke_callback, Tuple{FCallback}) + +# https://github.com/JuliaLang/julia/issues/41694 +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