Skip to content

Metal: run-time Symbol comparison takes the wrong branch after #960 #964

Closed

Description

@maleadt

Since #960, comparing a run-time Symbol against several constant symbols compiles for Metal, but picks the wrong branch for one of the values. Before #960, the same kernel failed to compile with Relocation slot '…jl_sym_acq_rel…' still has uses after redirection, so this went from a compile error to a wrong result.

using Metal
pick_sym(i) = i == 1 ? :monotonic : i == 2 ? :acquire : i == 3 ? :seq_cst : i == 4 ? :acq_rel : :release
@inline classify(s) =
    s === :monotonic ? 1 :
    s === :acquire ? 2 :
    s === :release ? 3 :
    (s === :acq_rel || s === :acquire_release) ? 4 :
    (s === :seq_cst || s === :sequentially_consistent) ? 5 :
    s === :unordered ? 6 : -1
k(a, sel) = (a[1] = classify(pick_sym(sel[1])); nothing)
function main()
    for i in 1:5
        a = MtlArray(Int32[0]); sel = MtlArray([i])
        @metal threads=1 k(a, sel)
        println(i, " ", pick_sym(i), " => ", Array(a)[1], " (expected ", classify(pick_sym(i)), ")")
    end
end
main()
1 monotonic => 1 (expected 1)
2 acquire => 2 (expected 2)
3 seq_cst => -1 (expected 5)
4 acq_rel => 4 (expected 4)
5 release => 3 (expected 3)

GPUCompiler main (037ef5a), Metal.jl 1.x with #977, Julia 1.12.7, M1. The IR returned by compile(:llvm, job) is still correct: the phi of slot addresses, the load from it and the comparisons against the jl_sym_seq_cst slot all look right. So the wrong result comes from the :table lowering or later.

This is how UnsafeAtomics 0.4 selects an ordering passed as a run-time Symbol (JuliaConcurrent/UnsafeAtomics.jl#30), so UnsafeAtomics.add!(p, x, sym) with sym == :seq_cst throws "invalid atomic ordering" on the device. Unions of ordering objects work correctly after #960.

Activity

  1. added theissue type on Oct 19, 2026
  2. added
    metalStuff about the Apple metal back-end.
    on Oct 19, 2026
  3. maleadt commented on Oct 19, 2026

    @maleadt
    MemberAuthor

    Fixed by #975: the :table lowering now loads relocation words as integers instead of as AS 0 pointers, which lose their high bits when loaded from device memory on Metal.

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

    metalStuff about the Apple metal back-end.

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions