-
-
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
Unreachable reached at 0x7fb1e395276a
, Illegal instruction
#52168
Comments
Reproduced outside of testing, the trace should be much smaller: https://julialang-dumps.s3.amazonaws.com/reports/2023-11-14T18-43-57-nsajko.tar.zst |
Also reproduces on Julia v1.10.0-rc1, but not not v1.9. |
No-dependency reproducer: module Repro
module TupleUtils
const NT = NTuple{n,Any} where {n}
const OneAndUp = Tuple{Any,Vararg{Any,n}} where {n}
const TwoAndUp = Tuple{Any,Any,Vararg{Any,n}} where {n}
rt(::T) where {n, T<:NT{n}} = NTuple{n,eltype(T)}
rt(::L, ::R) where {m, n, L<:NT{m}, R<:NT{n}} = NTuple{m + n, Union{eltype(L), eltype(R)}}
function concat(l::L, r::R) where {m, n, L<:NT{m}, R<:NT{n}}
f = let l = l, r = r
(i::Int) -> (i ≤ m) ? l[i] : r[i - m]
end
ntuple(f, Val(m + n))::rt(l, r)
end
function flatten(t::NTuple{n,NT{2}}) where {n}
f = let t = t
function(i::Int)
j = i - firstindex(t)
k = j >>> true
l = j % Bool
t[begin + k][begin + l]
end
end
ntuple(f, Val(2*n))
end
function tuple_slice(
t::OneAndUp{nm1}, ::Val{first}, ::Val{last},
) where {nm1, first, last}
m = last - first + 1
(m < 0) && error("expected nonnegative, got $m")
let n = nm1 + 1
(m ≤ n) || error("expected ordered, got ($m, $n)")
end
f = let t = t
(i::Int) -> t[first + i - 1]
end
ntuple(f, Val(m))
end
function interleave(l::L, r::R) where {m, L<:NT{m}, R<:NT{m}}
f = let l = l, r = r
function(i::Int)
j = i - 1
k = j >>> true
iseven(j) ? l[begin + k] : r[begin + k]
end
end
ntuple(f, Val(2*m))::rt(l, r)
end
function interleave_impl(l::L, r::R, ::Val{false}) where {m, n, L<:NT{m}, R<:NT{n}}
(m ≤ n) && error("internal error")
x = lastindex(l) - (m - n)
l_core = tuple_slice(l, Val(firstindex(l)), Val(x))::NT{n}
l_rest = tuple_slice(l, Val(x + 1), Val(lastindex(l)))::NT{m - n}
concat(interleave(l_core, r), l_rest)
end
function interleave_impl(l::L, r::R, ::Val{true}) where {m, n, L<:NT{m}, R<:NT{n}}
(n ≤ m) && error("internal error")
x = lastindex(r) - (n - m)
r_core = tuple_slice(r, Val(firstindex(r)), Val(x))::NT{m}
r_rest = tuple_slice(r, Val(x + 1), Val(lastindex(r)))::NT{n - m}
concat(interleave(l, r_core), r_rest)
end
interleave(l::L, r::R) where {m, n, L<:NT{m}, R<:NT{n}} = interleave_impl(l, r, Val(m < n))
function deinterleave_half(t::T) where {n, T<:OneAndUp{n}}
m = n + 1
t::NT{m}
h = m >>> true
g = m - h
f = let t = t
(i::Int) -> t[begin + 2*(i - 1)]
end
ntuple(f, Val(g))
end
deinterleave( t::Tuple{T}) where {T} = (t, ())
deinterleave_backwards(t::Tuple{T}) where {T} = ((), t)
deinterleave(t::T) where {T<:TwoAndUp} = (
deinterleave_half(t),
deinterleave_half(tuple_slice(t, Val(2), Val(lastindex(t)))),
)
deinterleave_backwards(t::T, ::Val{false}) where {T<:TwoAndUp} = deinterleave(t)
deinterleave_backwards(t::T, ::Val{true}) where {T<:TwoAndUp} = (
deinterleave_half(tuple_slice(t, Val(2), Val(lastindex(t)))),
deinterleave_half(t),
)
deinterleave_backwards(t::T) where {T<:TwoAndUp} =
deinterleave_backwards(t, Val(length(t) % Bool))
end
module Merging
import ..TupleUtils
const Ord = Base.Order
const NT = TupleUtils.NT
const OneAndUp = TupleUtils.OneAndUp
const tuple_slice = TupleUtils.tuple_slice
const rt = TupleUtils.rt
const deinterleave = TupleUtils.deinterleave
const interleave = TupleUtils.interleave
function even_odd_clean(mm::Mm, t::NT{n}) where {Mm, n}
iseven(n) || error("expected even, got $n")
f = let mm = mm, t = t
function(i::Int)
j = i - firstindex(t)
k = 2 * j
mm(t[begin + k], t[begin + k + 1])
end
end
TupleUtils.flatten(ntuple(f, Val(n >>> true)))::rt(t)
end
function even_odd_clean_abs(
mm::Mm, t::NT{n}, ::First, ::Last,
) where {Mm, n, first, last, First<:Val{first}, Last<:Val{last}}
s = tuple_slice(t, First(), Last())
f = let x = even_odd_clean(mm, s), t = t
i -> (first ≤ i ≤ last) ? x[i - first + 1] : t[i]
end
ntuple(f, Val(n))::rt(t)
end
function even_odd_clean_rel(mm::Mm, t::NT{n}, ::Val{f}, ::Val{b}) where {Mm, n, f, b}
k = Val(firstindex(t) + f)
l = Val( lastindex(t) - b)
even_odd_clean_abs(mm, t, k, l)::rt(t)
end
merge_oblivious_sd(::Tuple{}, ::Tuple{}, ::Any) = ()
merge_oblivious_sd(::Tuple{}, t::OneAndUp, ::Any) = t
merge_oblivious_sd(t::OneAndUp, ::Tuple{}, ::Any) = t
merge_oblivious_sd(l::Tuple{L}, r::Tuple{R}, mm::Mm) where {L, R, Mm} =
mm(only(l), only(r))::rt(l, r)
comparator_count_check(::V, ::V) where {V<:Val} = nothing
comparator_count_check(::Val{e}, ::Val{g}) where {e, g} =
error("wrong comparator count, expected $e, got $g")
conditionally_split_single_from_end(::Val{false}, x::T) where {T<:Tuple} = (x, ())
conditionally_split_single_from_end(::Val{true}, x::T) where {T<:OneAndUp} =
(tuple_slice(x, Val(firstindex(x)), Val(lastindex(x) - 1)), (last(x),))
function merge_oblivious_sd(
l::L, r::R, mm::Mm,
) where {m, n, L<:OneAndUp{m}, R<:OneAndUp{n}, Mm}
(s, t) = TupleUtils.deinterleave_backwards(l)
(u, v) = deinterleave(r)
x = merge_oblivious_sd(s, u, mm)
y = merge_oblivious_sd(t, v, mm)
total = 2 + m + n
(start, fin) = map(iseven, (m + 1, n + 1))
cld = n -> n - (n >>> true)
let exp = cld(m + 1) + cld(n + 1) - 1, got = (total - (start + fin)) >>> true
comparator_count_check(Val(exp), Val(got))
end
T = rt(l, r)
(y1, y2) = conditionally_split_single_from_end(Val(fin), y)
i = interleave(x, y1)
res = even_odd_clean_rel(mm, i, Val(start), Val(0))
ret = TupleUtils.concat(res, y2)
ret::T
end
end
repro(l, r) = Merging.merge_oblivious_sd(l, r, minmax)
end
l = (1,2,3,4,missing)
r = (1,2,3,4,5)
Repro.repro(l, r) Calling it: julia> versioninfo()
Julia Version 1.11.0-DEV.918
Commit 2fb06a7c25f (2023-11-16 07:19 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
WORD_SIZE: 64
LLVM: libLLVM-15.0.7 (ORCJIT, znver2)
Threads: 1 on 8 virtual cores
Environment:
JULIA_NUM_PRECOMPILE_TASKS = 3
JULIA_PKG_PRECOMPILE_AUTO = 0
julia> include("/home/nsajko/julia_issue_52168/julia_issue_52168.jl")
Unreachable reached at 0x7f4f42d0cae6
[75173] signal 4 (2): Illegal instruction
in expression starting at /home/nsajko/julia_issue_52168/julia_issue_52168.jl:193
merge_oblivious_sd at /home/nsajko/julia_issue_52168/julia_issue_52168.jl:181
repro at /home/nsajko/julia_issue_52168/julia_issue_52168.jl:187
unknown function (ip: 0x7f4f42d0cb79)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-master/src/julia.h:2130 [inlined]
do_call at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:126
eval_value at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:223
eval_stmt_value at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:174 [inlined]
eval_body at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:641
jl_interpret_toplevel_thunk at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:795
jl_toplevel_eval_flex at /cache/build/builder-amdci5-1/julialang/julia-master/src/toplevel.c:941
jl_toplevel_eval_flex at /cache/build/builder-amdci5-1/julialang/julia-master/src/toplevel.c:884
ijl_toplevel_eval_in at /cache/build/builder-amdci5-1/julialang/julia-master/src/toplevel.c:992
eval at ./boot.jl:425 [inlined]
include_string at ./loading.jl:2133
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
_include at ./loading.jl:2193
include at ./sysimg.jl:38
unknown function (ip: 0x7f4f42d0ba55)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-master/src/julia.h:2130 [inlined]
do_call at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:126
eval_value at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:223
eval_stmt_value at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:174 [inlined]
eval_body at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:641
jl_interpret_toplevel_thunk at /cache/build/builder-amdci5-1/julialang/julia-master/src/interpreter.c:795
jl_toplevel_eval_flex at /cache/build/builder-amdci5-1/julialang/julia-master/src/toplevel.c:941
jl_toplevel_eval_flex at /cache/build/builder-amdci5-1/julialang/julia-master/src/toplevel.c:884
ijl_toplevel_eval_in at /cache/build/builder-amdci5-1/julialang/julia-master/src/toplevel.c:992
eval at ./boot.jl:425 [inlined]
eval_user_input at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/share/julia/stdlib/v1.11/REPL/src/REPL.jl:167
repl_backend_loop at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/share/julia/stdlib/v1.11/REPL/src/REPL.jl:263
#start_repl_backend#48 at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/share/julia/stdlib/v1.11/REPL/src/REPL.jl:248
start_repl_backend at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/share/julia/stdlib/v1.11/REPL/src/REPL.jl:245
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
#run_repl#61 at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/share/julia/stdlib/v1.11/REPL/src/REPL.jl:404
run_repl at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/share/julia/stdlib/v1.11/REPL/src/REPL.jl:390
jfptr_run_repl_12730 at /home/nsajko/.julia/compiled/v1.11/REPL/u0gqU_YU6QH.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
#1078 at ./client.jl:440
jfptr_YY.1078_17045 at /home/nsajko/.julia/compiled/v1.11/REPL/u0gqU_YU6QH.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-master/src/julia.h:2130 [inlined]
jl_f__call_latest at /cache/build/builder-amdci5-1/julialang/julia-master/src/builtins.c:868
#invokelatest#2 at ./essentials.jl:928 [inlined]
invokelatest at ./essentials.jl:925 [inlined]
run_main_repl at ./client.jl:424
repl_main at ./client.jl:561 [inlined]
_start at ./client.jl:535
jfptr__start_65700.1 at /home/nsajko/tmp/jl/jl/julia-2fb06a7c25/lib/julia/sys.so (unknown line)
_jl_invoke at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:2910 [inlined]
ijl_apply_generic at /cache/build/builder-amdci5-1/julialang/julia-master/src/gf.c:3092
jl_apply at /cache/build/builder-amdci5-1/julialang/julia-master/src/julia.h:2130 [inlined]
true_main at /cache/build/builder-amdci5-1/julialang/julia-master/src/jlapi.c:586
jl_repl_entrypoint at /cache/build/builder-amdci5-1/julialang/julia-master/src/jlapi.c:738
main at /cache/build/builder-amdci5-1/julialang/julia-master/cli/loader_exe.c:58
unknown function (ip: 0x7f4f49671ccf)
__libc_start_main at /usr/lib/libc.so.6 (unknown line)
unknown function (ip: 0x4010b8)
Allocations: 2039268 (Pool: 2039171; Big: 97); GC: 3
Illegal instruction (core dumped) |
MWE julia> f(x, t::Type) = x::NTuple{2, Base.inferencebarrier(t)::Type}
f (generic function with 1 method)
julia> f((1, 2.), Any)
Unreachable reached at 000001f3c3460974 |
This function asserts a julia> @code_typed f((1,2.),Any)
CodeInfo(
1 ─ %1 = Base.compilerbarrier(:type, t)::Any
│ Core.typeassert(%1, Main.Type)::Type
│ %3 = π (%1, Type)
│ %4 = Core.apply_type(Main.NTuple, 2, %3)::Type{Tuple{T, T}} where T
│ Core.typeassert(x, %4)::Union{}
│ π (x, Union{})
└── unreachable
) => Union{} This then gets compiled to just a trap/unreachable. |
The mistake here is that |
But the result of julia> NTuple{2,Any} isa Type{Tuple{T, T}} where T
true Edit: in fact we can reproduce this on 1.9 with julia> f(x, @nospecialize t::Type{Tuple{T,T}} where {T}) = Core.typeassert(x, t)
f (generic function with 1 method)
julia> f((1, 1.), NTuple{2,Any})
Unreachable reached at 000001f34e590e38 |
That is fair. It looks like this is a peculiar corner case of when the diagonal rule doesn't apply because the julia> Type{Tuple{Any,Any}} <: Type{Tuple{T, T}} where T
true
julia> Type{Tuple{Any,Any}} <: Type{Tuple{T, T} where T<:S} where S
false However the implementation of
We have a variety of similar issues, such as: #24582 and #27031 (and included there is a link to a possible "diagonalize_unionall" helper function that might help solve that conundrum vtjnash@fa2f102#diff-18f6a8f71bb7339fa2e860328beeaaffaa7675ef7125dd5f6005dc65f91b5b3eR386) |
Testing an in-development version of my package reproducibly reaches unreachable. RR trace obtained with
julia --bug-report=rr
: https://julialang-dumps.s3.amazonaws.com/reports/2023-11-14T18-13-29-nsajko.tar.zstAs far as I understand the source of my package isn't necessary given the RR trace? In any case, I think this is a type inference issue because the stack trace point to a line that includes a type assertion.
I'm not sure if the Rr trace contains the relevant info, considering that unreachable gets reached during testing. Inform me if another Rr trace is needed.
This is with nightly Julia:
julia> versioninfo() Julia Version 1.11.0-DEV.894 Commit 9754dbbde5c (2023-11-13 18:40 UTC) Build Info: Official https://julialang.org/ release Platform Info: OS: Linux (x86_64-linux-gnu) CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics WORD_SIZE: 64 LLVM: libLLVM-15.0.7 (ORCJIT, znver2) Threads: 1 on 8 virtual cores Environment: JULIA_NUM_PRECOMPILE_TASKS = 3 JULIA_PKG_PRECOMPILE_AUTO = 0
Stack trace:
The text was updated successfully, but these errors were encountered: