Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Intel's CPU OpenCL runtime segfaults in X86 instruction selection when building an AcceleratedKernels scan kernel

Open
#600 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
julia
Domain
backend, devtools

Research direction

Start with the gist’s crash.spv and text forms, then compare the failing kernel with the two variants described in the issue. The report says the crash is in Intel’s runtime and has not been reduced to a small kernel; reproduce with the provided Julia or C commands and inspect whether a minimal reproducer can be produced. Done means a reduced reproducer is suitable for reporting to intel/llvm; the issue identifies no OpenCL.jl change to make.

Written by the indexing model from the issue text.

Description

Intel's CPU OpenCL runtime (2026.21) segfaults while building one of AcceleratedKernels.jl's scan kernels from the SPIR-V that OpenCL.jl generates. The crash is in the runtime's LLVM backend, in X86 instruction selection, at a null-pointer load. The same module validates with spirv-val. It is a driver bug, not an OpenCL.jl one, so this issue mainly tracks it. Once it is reduced further, it should be reported to intel/llvm.

The kernel is the tile scan of AK.accumulate! with an operator that has no known neutral element. AK then keeps partial results as Optional{Float32, Bool} (a value plus a Bool flag) in local memory, and combines two of them without branches:

sa, sb = isset(a), isset(b)
value = sa & sb ? op(a.value, b.value) : ifelse(sa, a.value, b.value)
return Optional(value, sa | sb)

That is the combine of JuliaGPU/AcceleratedKernels.jl#194. Two variants of the same kernel build and run fine:

  • the older combine, which branches and returns one of the operands (AK main);
  • a flag as wide as the value (UInt32 here), which AK uses for its Optional partials since #192/#195.

JuliaGPU/AcceleratedKernels.jl#195 keeps the wide flag on this runtime, so AK users won't hit this crash.

Environment
  • Intel CPU OpenCL runtime 2026.21.3.0.31_160000 (libintelocl.so.2026.21.3.0), OpenCL 3.0, on an AMD Ryzen 9 9950X (Zen 5, AVX-512), Arch Linux, kernel 7.2.11
  • Julia 1.12.7, OpenCL.jl 1.0.0, OpenCL_jll 2024.10.24+1, SPIRV_LLVM_Backend_jll 23.1.1+8, SPIRV_Tools_jll 2025.4.0+0, GPUCompiler 2.19.0, KernelAbstractions 0.10.4
  • AcceleratedKernels.jl at a4a4543 (the head of #194)

The runtime is the only OpenCL platform visible (OCL_ICD_VENDORS=/nonexistent OCL_ICD_FILENAMES=/opt/intel/oneapi/compiler/latest/lib/libintelocl.so).

Reproducer

In this gist: crash.spv, the SPIR-V module OpenCL.jl passes to clCreateProgramWithIL (dumped with JULIA_OPENCL_DUMP_DIR). Also there are its text forms: crash.spvasm (spirv-dis), crash.spt (llvm-spirv -to-text) and crash.ll (llvm-spirv -r).

Building that module is enough to crash the runtime:

using OpenCL
prog = cl.Program(; il=read("crash.spv"))
cl.build!(prog)   # segfaults

The same happens without Julia, with a small C program that calls clCreateProgramWithIL and clBuildProgram with no options on the first device (build_il.c, in the gist).

With AcceleratedKernels.jl at a4a4543:

using OpenCL
import AcceleratedKernels as AK
x = CLArray(rand(Float32, 10^6))
max2(a, b) = max(a, b)   # no known neutral element, unlike `max`
AK.accumulate!(max2, x; init=0f0)   # segfaults while compiling `gpu_scan_tile_kernel!`

I haven't reduced it to a small kernel yet. llvm-reduce on crash.ll (testing for a SIGSEGV in X86 instruction selection after llvm-spirv) ends up with modules that crash for unrelated reasons, introduced by the reduction itself. For example, a declaration loses an argument, or a kernel gets an aggregate by-value parameter. The runtime crashes on several such near-trivial modules too, in instruction selection or in its VPlan vectorizer. A clean hand-written kernel doing the same { float, i8 } loads and stores in local memory builds fine.

Crash output and backtrace

The runtime's own report, then Julia's backtrace (the library is stripped, so the frames have no names):

PLEASE submit a bug report to https://software.intel.com/en-us/support/priority-support and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0.	Running pass 'Function Pass Manager' on module 'main'.
1.	Running pass 'X86 DAG->DAG Instruction Selection' on function ''

[1931124] signal 11 (1): Segmentation fault
in expression starting at repro_ak.jl:10
syscall at /usr/lib/libc.so.6 (unknown line)
unknown function (ip: 0x7fe19ea5de84) at /opt/intel/oneapi/compiler/latest/lib/libintelocl.so
unknown function (ip: 0x7fe1f0e3e6ef) at /usr/lib/libc.so.6
unknown function (ip: 0x7fe19c0a249c) at /opt/intel/oneapi/compiler/latest/lib/libintelocl.so
unknown function (ip: 0x7fe19c09b24b) at /opt/intel/oneapi/compiler/latest/lib/libintelocl.so
...

Under gdb, the fault is a load through a null pointer, at offset 0x2ca249d of libintelocl.so.2026.21.3.0:

Thread 1 "julia" received signal SIGSEGV, Segmentation fault.
=> 0x7fffa2ea249d:	mov    (%rdi),%rax          ; rdi = 0
   0x7fffa2ea24a0:	mov    (%rax),%r14
   0x7fffa2ea24a3:	mov    0xa28(%r14),%eax

backtrace (offsets into libintelocl.so.2026.21.3.0):
#0  +0x2ca249d
#1  +0x2c9b24c
#2  +0x2c9ab9f
#3  +0x2c9a19d
#4  +0x2c9a003
#5  +0x325dd5e
#6  +0x325ba10
#7  +0x32a9952
#8  +0x2c23b68
#9  +0x2db4848
#10 +0x2db429c
#11 +0x2daebbe
#12 +0x3c31bb0
#13 +0x4115803
...
#35 +0x3c2886e
#36 libtbb.so.12
#37 +0x3c26414
...
Dominant language
Julia
Stars
313
Forks
50
Avg merge
1d 8h
Merged PRs (30d)
44

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from JuliaGPU/OpenCL.jl

All issues in JuliaGPU/OpenCL.jl

Similar issues

More Julia issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.