`lower_throw!` treats any function whose name contains `jl_error` etc. as a throw (kernel becomes a trap / segfault)

Đang mở Phù hợp với người mới
#1,088 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@sasmith-14 đang làm issue này rồi.

Từ ngày 12/11/2026.

  • #1089 của @sasmith-14 — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
75/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
julia
Lĩnh vực
compilers

Hướng nghiên cứu

Bắt đầu với lower_throw! trong src/irgen.jl, khoảng dòng 180–198, và các helper kiểm thử PTX được nêu trong issue. Kiểm tra cách so khớp tên hàm xử lý khai báo so với các hàm có thân, sau đó thêm một kiểm thử hồi quy dùng reproducer handle_jl_error đã được báo cáo. Công việc hoàn tất khi lời gọi hàm thông thường và store vẫn còn trong LLVM được tạo ra, trong khi các hàm throw thực sự vẫn được hạ thành báo cáo ngoại lệ và trap.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

lower_throw! picks the throw functions with a substring match on the name:
https://github.com/JuliaGPU/GPUCompiler.jl/blob/6c73a0ec7d0ac2a931e215f4954ce2373e72187e/src/irgen.jl#L180-L198

so a normal Julia function whose name contains jl_error, jl_throw, jl_bounds_error etc. is treated as a throw too: its calls get erased and replaced by an exception report + trap. on PTX the kernel just becomes a trap, and on Metal it segfaults during compilation.

i came across this while going through lower_throw! with claude, not by hitting it in real code, so it's a corner case. the Metal crash made it seem worth fixing though.

repro on PTX (no GPU needed, uses the test helpers; run from a GPUCompiler checkout with julia --project):

using GPUCompiler, LLVM
include("test/helpers/runtime.jl"); include("test/helpers/ptx.jl")

@noinline handle_ok(x::Int)       = x > 0 ? x + 1 : x - 1
@noinline handle_jl_error(x::Int) = x > 0 ? x + 1 : x - 1   # same body, only the name differs
k_ok(p::Ptr{Int}, x::Int)  = (unsafe_store!(p, handle_ok(x)); nothing)
k_bad(p::Ptr{Int}, x::Int) = (unsafe_store!(p, handle_jl_error(x)); nothing)

PTX.code_llvm(stdout, k_ok,  Tuple{Ptr{Int},Int}; dump_module=true)
PTX.code_llvm(stdout, k_bad, Tuple{Ptr{Int},Int}; dump_module=true)

k_ok keeps the call and the store:

  %0 = call fastcc i64 @julia_handle_ok_1536(i64 signext %"x::Int64")
  store i64 %0, ptr %"p::Ptr", align 1
  ret void

k_bad only has the trap left:

  call fastcc void @gpu_report_exception()
  call fastcc void @gpu_signal_exception()
  call void @llvm.trap()
  unreachable

on Metal (1.12.0) the same thing crashes Julia:

using Metal
@noinline handle_ok(x::Int)       = x > 0 ? x + 1 : x - 1
@noinline handle_jl_error(x::Int) = x > 0 ? x + 1 : x - 1
k_ok(a, x)  = (a[1] = handle_ok(x); nothing)
k_bad(a, x) = (a[1] = handle_jl_error(x); nothing)

a = Metal.zeros(Int, 1)
@metal k_ok(a, 5);  Array(a)[1]   # 6
@metal k_bad(a, 5)                # signal 11

the segfault is in llvm::Value::getContext while cloning a StoreInst. probably because the call is erased without replacing its uses, so the store ends up pointing at a deleted value.

the real throw functions are always declarations, so skipping functions that have a body (isdeclaration(f) || continue) fixes it and keeps the name matching as is. i'll open a PR with that and a test.

versions
Julia Version 1.13.3
Commit 67ac47b9cd8 (2026-10-25 15:28 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin27.0.0)
  CPU: 10 × Apple M5
  LLVM: libLLVM-20.1.8 (ORCJIT, apple-m1)

GPUCompiler v2.22.2 (main, 6c73a0e)
LLVM.jl v10.4.3
Metal.jl v1.12.0 (crashes with the registered GPUCompiler v2.22.2 and v2.22.0)
Ngôn ngữ chính
Julia
Star
191
Fork
73
Merge trung bình
17 giờ 5 phút
Pull request đã merge (30 ngày)
43

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của JuliaGPU/GPUCompiler.jl

Tất cả issue của JuliaGPU/GPUCompiler.jl

Issue tương tự

Thêm issue về Julia

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.