-
-
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
@code_warntype with non-specialized type arguments shows the wrong specialization #23749
Comments
The result is correct in that it is what the inference see and uses. Even though the functions is not specialized, the caller will still have good type info. julia> @noinline foo(t::Type, b) = t(b)
foo (generic function with 1 method)
julia> g() = foo(Int, 1.0)
g (generic function with 1 method)
julia> @code_warntype g()
Variables:
#self# <optimized out>
Body:
begin
return $(Expr(:invoke, MethodInstance for foo(::Type{T} where T, ::Float64), :(Main.foo), :(Main.Int), 1.0))::Int64
end::Int64
julia> @code_llvm g()
; Function g
; Location: REPL[1]
define i64 @julia_g_63641() #0 {
top:
%0 = alloca %jl_value_t addrspace(10)*, i32 3
; Location: REPL[1]:1
%1 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %0, i32 0
store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139909964693592 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %1
%2 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %0, i32 1
store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139909964646192 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %2
%3 = getelementptr %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %0, i32 2
store %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139909975372304 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %3
%4 = call %jl_value_t addrspace(10)* @jl_invoke(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139910009557776 to %jl_value_t*) to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %0, i32 3)
%5 = bitcast %jl_value_t addrspace(10)* %4 to i64 addrspace(10)*
%6 = load i64, i64 addrspace(10)* %5, align 8
ret i64 %6
} Automatically including specialization will be confusing since the function does not have any type instability, which is what |
Then consider function foo2(t::Type)
x = ones(t, 10)
return sum(map(sin, x))
end
|
There's no true type instability since you'll see that the result will be correctly inferred for all callers. It's just not getting specialized. I do agree it's confusing and we should improve tooling. However, the way to improve it is not to hide the difference. Rather, we should make it possible to see both results (we do now) but make it clear to the user (when we print the result) that they should be aware of what they are getting. |
I agree that both versions are useful in their own ways, however
The In any case, it seems that Wouldn't it be more natural if all of the |
It is inferred, just not specialized. Note that it does not mean there's a performance issue. If the code is inlined, for example, it won't matter at all.
Right, and I'm saying we should add/fix the logic for a similar warning. The code that actually runs is a more complicated question than what |
+1 to having |
We now have a function for computing this ( If someone wants to inject this message into the result, just be aware that the text should clarify that this widening for compilation does not affect inlining or the inferred return-type. |
Dup of #32834. This one was earlier but it is unclear which one is best to be kept open. |
I was informed in #23471 that functions that accept
::Type
(vs.::Type{T} where T
) do not specialize on that argument. However,@code_warntype
shows a specialized function body (on 0.6):This is confirmed by looking at the specializations:
I'm guessing that the correct outcome is this:
The text was updated successfully, but these errors were encountered: