Skip to content

LLVM SPIR-V backend crashes on functions returning small static arrays (e.g. SMatrix{1,1,Float32}) #422

@ChrisRackauckas-Claude

Description

@ChrisRackauckas-Claude

Summary

The LLVM SPIR-V backend (llc from SPIRV_LLVM_Backend_jll) crashes with LLVM ERROR: Broken function found, compilation aborted! when compiling GPU kernels that call functions returning small static array types like SMatrix{1,1,Float32}.

The root cause is that SMatrix{1,1,Float32} gets lowered to LLVM type [1 x float], and the SPIR-V backend incorrectly transforms the return type to i32 during internal passes, causing the LLVM IR verifier to abort.

MWE

using OpenCL, pocl_jll, KernelAbstractions, StaticArrays

# A kernel that calls a function returning SMatrix{1,1,Float32}
# This gets lowered to `[1 x float]` in LLVM IR, which the SPIR-V backend miscompiles
@kernel function smatrix_return_kernel(out)
    i = @index(Global)
    A = SMatrix{1,1,Float32}(3.0f0)
    B = SMatrix{1,1,Float32}(2.0f0)
    C = A * B  # returns SMatrix{1,1,Float32}
    out[i] = C[1]
end

backend = OpenCL.OpenCLBackend()
out = KernelAbstractions.zeros(backend, Float32, 4)
kernel = smatrix_return_kernel(backend, 4)
kernel(out, ndrange=4)
KernelAbstractions.synchronize(backend)

Error output

LLVM ERROR: Broken function found, compilation aborted!
ERROR: LoadError: Failed to translate LLVM code to SPIR-V.
...
caused by: failed process: Process(`...llc ...`, ProcessSignaled(6)) [0]

Context

This was discovered via SciML/DiffEqGPU.jl, where stiff ODE solvers using autodiff=false call finite_diff_jac, which returns SMatrix types. The finite_diff.jl tests fail on all Julia versions (lts, 1, pre) when using the OpenCL backend. See https://github.com/SciML/DiffEqGPU.jl/actions/runs/22247943080/job/64365791848

The same kernels work correctly with CUDA, AMDGPU, and JLArrays backends. They also likely work with the Khronos SPIR-V translator (SPIRV_LLVM_Translator_jll), since this is specifically a bug in the LLVM native SPIR-V backend.

Environment

  • Julia: 1.10, 1.12, nightly (all affected)
  • OpenCL.jl: latest (MQ6HZ)
  • GPUCompiler.jl: latest (OCZFZ)
  • SPIRV_LLVM_Backend_jll: v20.1.5+3
  • pocl_jll (CPU OpenCL implementation)

Possibly related upstream

This appears related to LLVM's handling of struct/array return types in the SPIR-V backend. The SPIRV_LLVM_Backend_jll already carries patches for similar issues (e.g. fix_insertvalue.patch for LLVM#127977, atomic_cmpxchg_64bit.patch for LLVM#152863), but no patch exists yet for this specific struct-return miscompilation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions