The following example generates bad code on recent Julia releases (including master):
function foo(args...)
Base.pointerset(args[1], 1, 1, 1)
return
end
code_llvm(foo, Tuple{Ptr{Int}, Type{Int}})
define void @julia_foo_11773(i64, %jl_value_t addrspace(10)* nonnull) #0 {
top:
%2 = alloca %jl_value_t addrspace(10)*, i32 3
%gcframe = alloca %jl_value_t addrspace(10)*, i32 3, align 16
...
%19 = call nonnull %jl_value_t addrspace(10)* @jl_f_tuple(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* null to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %2, i32 2)
...
%24 = call nonnull %jl_value_t addrspace(10)* @jl_f_getfield(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* null to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %2, i32 3)
...
%25 = bitcast %jl_value_t addrspace(10)* %24 to i64* addrspace(10)*
%26 = load i64*, i64* addrspace(10)* %25, align 8
store i64 1, i64* %26, align 1
...
ret void
}
Not passing a Type{Int} (or any other non-concrete argument), or getting rid of the varargs, results in the expected clean code.
This doesn't look like an inference/specialization problem to me (i.e. not https://github.com/JuliaLang/julia/issues/34365):
julia> first(code_typed(foo, Tuple{Ptr{Int}, Type{Int}})[])
CodeInfo(
1 ─ %1 = Base.pointerset::Core.Compiler.Const(Core.Intrinsics.pointerset, false)
│ %2 = Base.getfield(args, 1, true)::Ptr{Int64}
│ (%1)(%2, 1, 1, 1)::Ptr{Int64}
└── return
)
julia> first(code_typed(foo, Tuple{Ptr{Int}, Type{Int}})[]).parent.specTypes
Tuple{typeof(foo),Ptr{Int64},Type{Int64}}
Instead, we get the tuple from the specsig but non-concrete varargs code path here: https://github.com/JuliaLang/julia/blob/0549bf1ce39071f22cb7c8065d99e8215714c063/src/codegen.cpp#L6177-L6202
This penalizes a lot of Cassette-based code, where splatting is used heavily for _every_ function call (overdub(ctx, args...)) and we get plenty calls to jl_f_tuple and jl_f_getfield as soon as passing a non-concrete argument (as observed in https://github.com/JuliaGPU/CUDAnative.jl/pull/334 where these calls break compilation).
Looks like I ran into this already: https://github.com/JuliaLang/julia/issues/27929. I'll close that issue since this has much more information.
Most helpful comment
Looks like I ran into this already: https://github.com/JuliaLang/julia/issues/27929. I'll close that issue since this has much more information.