On Julia 1.13.0-rc1, @report_opt produces runtime-dispatch reports for straightforward, fully-concrete Base code paths (broadcast, view, CartesianIndex construction, mightalias) that are reported clean on Julia 1.12.6 with the same JET version (0.11.5). Native inference of every flagged frame is concrete and dispatch-free on both versions, so these appear to be false positives in JET's analysis layer on 1.13 rather than Base inference regressions or real dispatches.
Found via ForwardDiff.jl's QA testset (JET.@test_opt over gradient/jacobian/hessian), which fails on all "Julia pre" CI jobs; reduced to the self-contained MWEs below.
MWEs (clean on 1.12.6, flagged on 1.13.0-rc1; JET 0.11.5 in both cases)
using JET
# 1. Type-constructor broadcast with a Ref argument — 1 report on 1.13-rc1
struct P{N,V}; v::NTuple{N,V}; end
struct D{T,V,N}; val::V; p::P{N,V}; end
seedlike!(d, x, p) = (d .= D{Nothing,Float64,1}.(x, Ref(p)); d)
@report_opt seedlike!(Vector{D{Nothing,Float64,1}}(undef, 3), rand(3), P{1,Float64}((1.0,)))
# runtime dispatch in Broadcast.preprocess (broadcast.jl:977):
# Broadcasted(nothing, …, %2::Tuple{Union{RefValue{…}, Extruded{…}}, RefValue{P{…}}}, …)
# (native inference of preprocess with these argtypes gives the concrete
# Tuple{Extruded{Vector{Float64},…}, RefValue{P{1,Float64}}} on both versions)
# 2. CartesianIndex from Int + CartesianIndex — 3 reports on 1.13-rc1
ci2(i, c) = CartesianIndex(i, c)
@report_opt ci2(1, CartesianIndex(2))
# flatten (multidimensional.jl:92): Tuple(%1::Union{Int64, CartesianIndex{1}})::Tuple
# Val(x::Int64) dispatch; CartesianIndex(%1::Tuple)::Any
# Also triggered by plain `@simd for I in CartesianIndices(::Matrix)` loops.
# 3. view with a Colon and a range — 2 reports on 1.13-rc1
viewmwe(A, r) = view(A, :, r)
@report_opt viewmwe(rand(3, 3), 1:2)
# SubArray(…, %1::Tuple{Union{Slice{…}, UnitRange{…}}, …}) at subarray.jl:28,
# including a union-split into the impossible argument order
# unsafe_view(::Matrix, ::UnitRange, ::Slice)
# 4. dotview + broadcast assignment (hits 3. plus mightalias/_isdisjoint/_in_tuple) —
# 10 reports on 1.13-rc1
dotviewmwe!(A, r, y) = (A[:, r] .= y .* transpose(y); A)
@report_opt dotviewmwe!(rand(3, 3), 1:2, rand(3))
Full suite: 23 reports on 1.13.0-rc1, 0 on 1.12.6.
Evidence these are analysis false positives, not real dispatches
Base.infer_return_type / code_typed with the exact argtypes from the reports is concrete and identical on 1.12.6 and 1.13.0-rc1, e.g. on rc1:
Base.infer_return_type(Base.IteratorsMD.flatten, (Tuple{Int,CartesianIndex{1}},)) == Tuple{Int, Int}
Base.infer_return_type(view, (Matrix{Float64}, Colon, UnitRange{Int})) is the concrete SubArray{Float64, 2, Matrix{Float64}, Tuple{Slice{OneTo{Int}}, UnitRange{Int}}, true}
Base.Broadcast.preprocess for MWE 1's broadcast infers the concrete Broadcasted{Nothing, …, Tuple{Extruded{…}, RefValue{…}}}
- Cache-cold inference through a minimal custom
AbstractInterpreter with a fresh cache_owner is equally concrete on rc1 (rules out warm-sysimage-cache masking).
- Runtime: the MWE kernels are 0-allocation on both versions (e.g.
@allocated seedlike!(…) == 0 on rc1), so no dynamic dispatch exists in the compiled code.
_in_tuple (flagged as a leaf in pattern 4) is not new 1.13 code — it exists verbatim in 1.12.6 operators.jl, where JET is silent about it.
The unifying shape seems to be that in nested frames, call-site type/constant refinement is lost, so tuple element access degrades to the union over all element types (t::Tuple{Int, CartesianIndex{1}}; t[i]::Union{Int, CartesianIndex{1}}) and Val(x) is no longer const-propagated. Shallow versions of the same operations (e.g. a direct ensure_indexable call, or a hand-written recursive tuple map) are still analyzed precisely.
Not fixed by #815
Re-running the full MWE suite with PatrickHaecker/JET.jl#julia-1.13-compat (PR #815) on 1.13.0-rc1 gives identical reports, so this seems to be a distinct problem from what that PR addresses. Possibly related to the constprop issues in #819 (typeassert InferenceState, got IRInterpretationState in const_prop_call on JET#master), but these reports are silent mis-analysis rather than a crash.
Versions: Julia 1.13.0-rc1 (official binaries via juliaup), JET 0.11.5 (also reproduced with 0.11.4 in ForwardDiff CI), Linux x86_64.
On Julia 1.13.0-rc1,
@report_optproduces runtime-dispatch reports for straightforward, fully-concrete Base code paths (broadcast,view,CartesianIndexconstruction,mightalias) that are reported clean on Julia 1.12.6 with the same JET version (0.11.5). Native inference of every flagged frame is concrete and dispatch-free on both versions, so these appear to be false positives in JET's analysis layer on 1.13 rather than Base inference regressions or real dispatches.Found via ForwardDiff.jl's QA testset (
JET.@test_optovergradient/jacobian/hessian), which fails on all "Julia pre" CI jobs; reduced to the self-contained MWEs below.MWEs (clean on 1.12.6, flagged on 1.13.0-rc1; JET 0.11.5 in both cases)
Full suite: 23 reports on 1.13.0-rc1, 0 on 1.12.6.
Evidence these are analysis false positives, not real dispatches
Base.infer_return_type/code_typedwith the exact argtypes from the reports is concrete and identical on 1.12.6 and 1.13.0-rc1, e.g. on rc1:Base.infer_return_type(Base.IteratorsMD.flatten, (Tuple{Int,CartesianIndex{1}},)) == Tuple{Int, Int}Base.infer_return_type(view, (Matrix{Float64}, Colon, UnitRange{Int}))is the concreteSubArray{Float64, 2, Matrix{Float64}, Tuple{Slice{OneTo{Int}}, UnitRange{Int}}, true}Base.Broadcast.preprocessfor MWE 1's broadcast infers the concreteBroadcasted{Nothing, …, Tuple{Extruded{…}, RefValue{…}}}AbstractInterpreterwith a freshcache_owneris equally concrete on rc1 (rules out warm-sysimage-cache masking).@allocated seedlike!(…) == 0on rc1), so no dynamic dispatch exists in the compiled code._in_tuple(flagged as a leaf in pattern 4) is not new 1.13 code — it exists verbatim in 1.12.6operators.jl, where JET is silent about it.The unifying shape seems to be that in nested frames, call-site type/constant refinement is lost, so tuple element access degrades to the union over all element types (
t::Tuple{Int, CartesianIndex{1}}; t[i]::Union{Int, CartesianIndex{1}}) andVal(x)is no longer const-propagated. Shallow versions of the same operations (e.g. a directensure_indexablecall, or a hand-written recursive tuple map) are still analyzed precisely.Not fixed by #815
Re-running the full MWE suite with
PatrickHaecker/JET.jl#julia-1.13-compat(PR #815) on 1.13.0-rc1 gives identical reports, so this seems to be a distinct problem from what that PR addresses. Possibly related to the constprop issues in #819 (typeassert InferenceState, got IRInterpretationStateinconst_prop_callon JET#master), but these reports are silent mis-analysis rather than a crash.Versions: Julia 1.13.0-rc1 (official binaries via juliaup), JET 0.11.5 (also reproduced with 0.11.4 in ForwardDiff CI), Linux x86_64.