-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow irinterp to refine nothrow effect #48066
Conversation
@@ -225,16 +225,21 @@ function reprocess_instruction!(interp::AbstractInterpreter, | |||
(; rt, effects) = abstract_eval_statement_expr(interp, inst, nothing, ir, irsv.mi) | |||
# All other effects already guaranteed effect free by construction | |||
if is_nothrow(effects) | |||
ir.stmts[idx][:flag] |= IR_FLAG_EFFECT_FREE | IR_FLAG_NOTHROW |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IR_FLAG_EFFECT_FREE
seems a bit risky here since we may prove :effect_free
-ness in a presence of effect-ful statement, e.g.
julia> mutable struct SafeRef{T}
x::T
end
julia> Base.getindex(x::SafeRef) = x.x
julia> Base.setindex!(x::SafeRef, y) = x.x = y
julia> Base.infer_effects((String,String,)) do x, y
r = SafeRef(x)
r[] = y
r[]
end
(+c,+e,+n,+t,+s,+m)
So I guess we need to check is_removable_if_unused
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're probably right, though IR_FLAG_EFFECT_FREE was there before, so this might be an existing bug. Ideally we should have a testcase for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I attempted to create a test case to trigger an error because of this issue, but it seems very difficult to invent one. Something like the example below would be close (it actually crashes due to a different bug in our SROA though).
Base.@assume_effects :consistent :nothrow @inline function foo(a::Int, b)
r = Ref(a)
try
setfield!(r, :x, b)
nothing
catch err
return isa(b, String)
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xref: #48067
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with move this forward leaving the correctness issue for the future.
47c47af
to
138e922
Compare
I looked into the I don't think that's really a bug with this PR, I'd like to just allow this case in the test. Maybe in the future we can separate out the caches between |
@nanosoldier |
I was investigating why LLVM was unable to remove the boundscheck that was causing the test failure in #48066 and it turned out that the check was removable by instcombine, but only if cvp ran first. However, we ran the passes in the opposite order and then loop-rotated the condition away before instcombine ran again. I think it makes sense to run cvp before instcombine to make sure that instcombine can make use of the overflow flags inferred by cvp. For the particular case in #48066, we also need https://reviews.llvm.org/D140933 (and we may need it in general, since we like to emit our conditionals as negations), but overall this seems like a better place for cvp in our pass pipeline.
#48110 + https://reviews.llvm.org/D140933 also makes the test work regardless by allowing LLVM to eliminate the boundscheck. However, I intend to decouple the two changes by allowing the failure here. |
Fine by me. |
Your package evaluation job has completed - possible new issues were detected. A full report can be found here. |
A bunch of packages are complaining about lack of |
|
To catch a case that occurs in FuncPipelines.jl and was causing precision issues in #48066.
To catch a case that occurs in FuncPipelines.jl and was causing precision issues in #48066.
To catch a case that occurs in FuncPipelines.jl and was causing precision issues in #48066.
This addresses a remaining todo in the irinterp code to allow it to compute whether its particular evaluation refined `nothrow`. As a result, we can re-enable it for a larger class of ir (we had previously disabled it to avoid regressing cases where regular constprop was able to prove a `nothrow` refinement, but irinterp was not).
138e922
to
7d36744
Compare
Ok, I've gone through all of them and they should be fixed between #48144 and #48110 and the changes I made here. A general trend was that we should probably generally make methods that we give effect overrides |
(Just to clarify) The problem here is that a :foldable method is no longer foldable during julia/base/compiler/ssair/irinterp.jl Line 151 in 7d36744
It might be a good idea to use the |
That's correct |
To catch a case that occurs in FuncPipelines.jl and was causing precision issues in #48066.
This addresses a remaining todo in the irinterp code to allow it to compute whether its particular evaluation refined
nothrow
. As a result, we can re-enable it for a larger class of ir (we had previously disabled it to avoid regressing cases where regular constprop was able to prove anothrow
refinement, but irinterp was not).