`lower_throw!` treats any function whose name contains `jl_error` etc. as a throw (kernel becomes a trap / segfault)
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 75/100
Línea de trabajo
Empieza con lower_throw! en src/irgen.jl, alrededor de las líneas 180–198, y con los helpers de pruebas PTX mencionados en el issue. Comprueba cómo la coincidencia del nombre de la función trata las declaraciones frente a las funciones con cuerpo y, después, añade una prueba de regresión usando el reproducer handle_jl_error indicado. El trabajo está terminado cuando la llamada a la función ordinaria y el store permanecen en el LLVM generado, mientras que las funciones throw reales siguen convirtiéndose en notificación de excepciones y un trap.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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)
- Lenguaje dominante
- Julia
- Estrellas
- 191
- Forks
- 73
- Merge medio
- 17 h 5 min
- PR fusionados (30 d)
- 43
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de JuliaGPU/GPUCompiler.jl
-
spirv
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
JuliaGPU/GPUCompiler.jl#1008 ·
Los mantenedores suelen responder en 1 día
-
SPIR-V runtime library fails to build on 32-bit hosts: `unbox_int64` returns voidPosiblemente ocupada @maleadt la tomó hace 18 días. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
JuliaGPU/GPUCompiler.jl#1085 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
JuliaGPU/GPUCompiler.jl#1074 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
JuliaGPU/GPUCompiler.jl#1060 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
JuliaGPU/GPUCompiler.jl#1050 ·
Los mantenedores suelen responder en 1 día
Todos los issues de JuliaGPU/GPUCompiler.jl
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
MagneticResonanceImaging/MRIReco.jl#366 ·
Los mantenedores suelen responder en 3 días
-
`AdamW` gives `NaN` for zero-gradient entries of `Float16` parameters (epsilon underflows to 0)Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 79/100
FluxML/Optimisers.jl#253 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
JuliaGraphs/GraphNeuralNetworks.jl#736 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día
-
`poissonians` is not public, unlike `brownians` and `jumps`Posiblemente ocupada @isaacsas la tomó hoy. Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 86/100
SciML/ModelingToolkit.jl#5389 ·
Los mantenedores suelen responder en 2 días