-
-
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
Fix inference with const opaque closure #42725
Conversation
If this fixes it, it seems like there is also a deeper underlying bug too that must be fixed also. |
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.
LGTM, since this pass is supposed to handle a case when only the data type of an opaque closure is known, and we should use widenconst
when working on Type
objects.
What is the tester_linuxaarch64 failure? It definitely seems unrelated, but maybe worth rebasing? |
Yes, but it is also unacceptable for it to return an incorrect answer just because this case couldn't be optimized |
Do you mean we need to fix something between the inference and codegen? But it looks like a correct codegen to me given the inference
|
Do we need other actions before merging this? Or should we close this PR and wait for a real fix? |
Yes, |
Hmm... I'm a bit confused. This PR fixes the inference Do you mean we need to fix this in |
It is supposed to be handled by the check on line 1378, for example, but it isn't reaching there apparently. |
Quoting the code in question: julia/base/compiler/abstractinterpretation.jl Lines 1370 to 1384 in e38184c
But we don't hit 1378 since julia/base/compiler/utilities.jl Lines 266 to 275 in 011fda9
(TBH, |
When
Yeah, at this moment all the usages of |
@@ -1370,7 +1370,7 @@ function abstract_call(interp::AbstractInterpreter, fargs::Union{Nothing,Vector{ | |||
f = singleton_type(ft) | |||
if isa(ft, PartialOpaque) | |||
return abstract_call_opaque_closure(interp, ft, argtypes[2:end], sv) | |||
elseif (uft = unwrap_unionall(ft); isa(uft, DataType) && uft.name === typename(Core.OpaqueClosure)) | |||
elseif (uft = unwrap_unionall(widenconst(ft)); isa(uft, DataType) && uft.name === typename(Core.OpaqueClosure)) |
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.
Maybe not directly related, but this kind of structural-only check causes a non-monotonicity:
julia> f() = Union{OC{Tuple{},Int8},OC{Tuple{},Int16}}[][1]()
julia> @code_typed f()
...
) => Any
julia> f() = OC{Tuple{},<:Integer}[][1]()
julia> @code_typed f()
...
) => Integer
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 it exist before this patch but I guess it'd be nice to fix it? I don't know what Keno's intention was, though.
What is the standard way to implement this? Would something like
elseif typeintersect(widenconst(ft), OpaqueClosure) <: OpaqueClosure
work? But I guess it still doesn't support Union{OC{Tuple{},Int8},Returns{Int16}}
?
I can open a follow-up PR to fix this once I understand how to do it.
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.
Looked into this closer, and I found this appear to be the other missing piece. This PR makes this unreachable by-and-large, but still the intended behavior of each function to do.
diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl
index ff674f2d91..83cc37cb50 100644
--- a/base/compiler/abstractinterpretation.jl
+++ b/base/compiler/abstractinterpretation.jl
@@ -1279,6 +1279,9 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
return abstract_modifyfield!(interp, argtypes, sv)
end
return CallMeta(abstract_call_builtin(interp, f, arginfo, sv, max_methods), false)
+ elseif isa(f, OpaqueClosure)
+ # calling an OpaqueClosure about which we have no information returns no information
+ return CallMeta(Any, false)
elseif f === Core.kwfunc
if la == 2
ft = widenconst(argtypes[2])
This reverts the bugfix part of commit 07f06d5 but keeps the test.
Co-authored-by: Jameson Nash <vtjnash@gmail.com>
@vtjnash Thanks, I was wondering if Is it good to go now? |
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.
actual correctness requires both patches
This reverts commit ec58338.
/buildkite rerun failed |
The failures seem unrelated. Maybe we can fix them by rebasing ? |
@tkf Can you rebase this on the latest master? That should fix the Downloads test failures. |
I am eventually going to implement a new Buildkite command that will automatically rerun the entire Buildkite job with the updated merge commit. Once I've done that, you won't need to rebase; you'll be able to run this new command. But it'll be a while before that is ready. |
I'm pretty sure this PR will be squash-merged. So it doesn't have to be rebased, I suppose? It's good to leave edit and CI history in the PR, which will be hard to reconstruct with rebase. |
Needs a manual backport. |
done backport |
Currently, using constant opaque closure (e.g., a global const or
@benchmark
#40409) introduces an illegal instruction error. MWE:This is because of the incorrect inference:
This seems to be simply due to a missing
widenconst
in inference.fix #40409