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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions