Skip to content

Metal: bus error in the LLVM inliner on dynamic code, instead of an InvalidIRError #965

Description

@maleadt

Compiling a Metal kernel that ends up with dynamic code crashes the process during optimization, instead of reporting an InvalidIRError:

using Metal, UnsafeAtomics   # UnsafeAtomics from JuliaConcurrent/UnsafeAtomics.jl#30
const UA = UnsafeAtomics
wrapper(p, x; kwargs...) = UA.add!(p, x, UA.monotonic, UA.device; kwargs...)
k(a) = (wrapper(pointer(a), Int32(1); volatile = true, align = 8); nothing)
@metal threads=1 k(MtlArray(Int32[0]))
[30093] signal 10 (1): Bus error: 10
_ZN12_GLOBAL__N_112CallAnalyzer7analyzeEv at .../libLLVM.dylib
llvm::getInlineCost(...)
...
llvm::InlinerPass::run(...)
...
llvm::ModuleInlinerWrapperPass::run(...)
LLVMRunJuliaPasses at LLVM/JGisQ/lib/18/libLLVM_extra.jl:319
run! at LLVM/JGisQ/src/newpm.jl:380
optimize_module! at GPUCompiler/src/metal.jl:425
optimize! at GPUCompiler/src/optim.jl:52
emit_llvm at GPUCompiler/src/driver.jl:176

GPUCompiler main (037ef5a), Julia 1.12.7, M1. The same crash happens with the Metal atomics branch (#942/#943). With #949, it crashed earlier instead, in check_allocation!/referenced_object.

The code is dynamic because Julia doesn't const-prop the keywords into the non-inlined wrapper, so align is a run-time value and Val(align) becomes a dynamic call to UnsafeAtomics' @generated llvmcall primitive. Base.@constprop :aggressive on the wrapper avoids it. Metal.code_llvm(…; optimize = false) works and gives about 2,400 lines of IR (typejoin, _growbeg!, boxing, …); the crash is in the LLVM inliner over that module. A similar kernel whose dynamic code doesn't involve llvmcall (wrapper(a, x; kwargs...) = store(a, x, Val(kwargs[:index]))) is correctly reported as an InvalidIRError.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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