julia icon indicating copy to clipboard operation
julia copied to clipboard

Type instability with `Base.promote_type` and Static.jl types for Julia v1.10-beta2 and `--check-bounds=no`

Open sloede opened this issue 2 years ago • 6 comments

When using Julia v1.10-beta2 with --check-bounds=no, using Static.jl types together with native types causes a type instability. In fact, it looks like Base.promote_type is not able to infer a concrete type at all anymore and just returns Any.

MWE (with julia-1.10-beta2 --check=bounds=no):

julia> using Pkg

julia> Pkg.activate(; temp=true, io=devnull)

julia> Pkg.add(name="Static", version="0.8.8", io=devnull)

julia> using Static

julia> i = 1; s = static(2);

julia> @code_warntype Base.promote_type(typeof(i), typeof(s))
MethodInstance for promote_type(::Type{Int64}, ::Type{StaticInt{2}})
  from promote_type(::Type{T}, ::Type{S}) where {T, S} @ Base promotion.jl:306
Static Parameters
  T = Int64
  S = StaticInt{2}
Arguments
  #self#::Core.Const(promote_type)
  _::Core.Const(Int64)
  _::Core.Const(StaticInt{2})
Body::Any
1 ─      nothing
│   %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64)
│   %3 = $(Expr(:static_parameter, 2))::Core.Const(StaticInt{2})
│   %4 = Base.promote_rule($(Expr(:static_parameter, 1)), $(Expr(:static_parameter, 2)))::Core.Const(Union{})
│   %5 = Base.promote_rule($(Expr(:static_parameter, 2)), $(Expr(:static_parameter, 1)))::Core.Const(Union{})
│   %6 = Base.promote_result(%2, %3, %4, %5)::Any
└──      return %6

The error does not occur if I use Julia v1.10 without --check-bounds=no or when using Julia v1.9 (with or without --check-bounds=no). On those cases, we get the following output for @code_warntype:

julia> @code_warntype Base.promote_type(typeof(i), typeof(s))
MethodInstance for promote_type(::Type{Int64}, ::Type{StaticInt{2}})
  from promote_type(::Type{T}, ::Type{S}) where {T, S} @ Base promotion.jl:306
Static Parameters
  T = Int64
  S = StaticInt{2}
Arguments
  #self#::Core.Const(promote_type)
  _::Core.Const(Int64)
  _::Core.Const(StaticInt{2})
Body::Type{Number}
1 ─      nothing
│   %2 = $(Expr(:static_parameter, 1))::Core.Const(Int64)
│   %3 = $(Expr(:static_parameter, 2))::Core.Const(StaticInt{2})
│   %4 = Base.promote_rule($(Expr(:static_parameter, 1)), $(Expr(:static_parameter, 2)))::Core.Const(Union{})
│   %5 = Base.promote_rule($(Expr(:static_parameter, 2)), $(Expr(:static_parameter, 1)))::Core.Const(Union{})
│   %6 = Base.promote_result(%2, %3, %4, %5)::Core.Const(Number)
└──      return %6

The issue first appeared when trying to use PtrArray from StrideArrays.jl (see also https://github.com/JuliaSIMD/StrideArrays.jl/issues/78). There, the failure to determine a usable promotion type propagates into a regular array access returning values of type Any, making the code unusably slow.

Thanks to @ranocha for creating a more minimum MWE. Maybe @vchuravy has an idea how to fix this (since he resolved a similar issue for v1.9 and StaticArrays.jl)?

cc @chriselrod

sloede avatar Aug 20 '23 09:08 sloede

I take it this is distinct from (though possibly indirectly related to) the issue discussed in https://github.com/JuliaLang/julia/pull/50239?

brenhinkeller avatar Aug 20 '23 17:08 brenhinkeller

On 1.9 with --check-bounds=no

 • %2 = < pure > typejoin(::Type{…},::Type{…})::Core.Const(Number) (+c,+e,+n,+t,+s,+m,+i)

On 1.10 with --check-bounds=no

 • %1 = invoke typejoin(::Type{Int64},::Type{StaticInt{2}})::Any (+c,+e,!n,+t,+s,+m,+i)

This might be #48684 cc: @aviatesk

I hoped #50561 would improve the situation, but it doesn't seem enough.

vchuravy avatar Aug 21 '23 13:08 vchuravy

Is this another consequence of the removal of @pure from some internals?

brenhinkeller avatar Aug 21 '23 15:08 brenhinkeller

Kinda, https://github.com/JuliaLang/julia/pull/48684 replaced special handling of the almost intrinsics. So it's more than just a removal of pure.

vchuravy avatar Aug 21 '23 20:08 vchuravy

Putting this on the milestone since we will need to fix this in either 1.10.0 or 1.10.x

vchuravy avatar Aug 22 '23 21:08 vchuravy

Talking with @Keno, it seems that this cannot really be fixed in 1.10 and has to wait for 1.11, see e.g. https://github.com/JuliaLang/julia/pull/50641. So I will take this off the milestone.

KristofferC avatar Sep 01 '23 14:09 KristofferC