Demote unordered atomic accesses for SPIR-V targets - #924
Merged
Conversation
Julia marks loads and stores of heap references `unordered`, so that a read
racing with the GC or with another thread's write cannot observe a torn
pointer. There is no device GC for these orderings to protect against, but
not every back-end can express them: SPIR-V's OpAtomicLoad/OpAtomicStore
only take scalar integer or floating-point operands, so the Khronos
translator turns an `unordered` load of a pointer into an invalid
pointer-typed atomic ("AtomicLoad: expected Result Type to be integer or
float scalar type" from spirv-val; Intel's compiler fails on an undefined
`__spirv_AtomicLoad(long**, int, int)`). The LLVM SPIR-V back-end already
lowers such loads to plain OpLoads. With oneAPI.jl gaining a device
allocator, kernels that read boxed fields now reach this on Julia 1.12+.
Move the Metal target's `demote_unordered_atomics!` next to the other
shared post-optimization rewrites and run it from the SPIR-V target's
`finish_ir!` too. The end-to-end test compiles an `unordered` pointer load
and store through both SPIR-V code paths with validation enabled.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #924 +/- ##
=======================================
Coverage 85.42% 85.42%
=======================================
Files 29 29
Lines 5583 5584 +1
=======================================
+ Hits 4769 4770 +1
Misses 814 814 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Member
Author
|
CI failure unrelated, looks like Julia+Asserts has regressed and fails to precompile e.g. Parsers.jl |
maleadt
added a commit
to JuliaLang/julia
that referenced
this pull request
Sep 6, 2026
Sinking an inner loop's `gc_preserve_end` to an exit that also leaves the loop containing its `gc_preserve_begin` makes the token live out of that outer loop. LCSSA cannot insert token PHIs, so subsequent loop cloning can leave uses that are no longer dominated by their definition. This causes a verifier failure while precompiling Parsers 3.0.0 on Julia 1.12 with LLVM assertions in JuliaGPU/GPUCompiler.jl#924. Only sink ends to exits within the begin's loop, or to any exit if the begin is outside all loops. Omitting an end conservatively extends the preserve region, which GC lowering already supports. CI failure: https://github.com/JuliaGPU/GPUCompiler.jl/actions/runs/34050391805/job/101532856212 Assisted-by: Claude Code (Fable 5.1) Assisted-by: Codex (GPT-6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Julia marks loads and stores of heap references
unordered, so that a read racing with the GC or with another thread's write cannot observe a torn pointer. There is no device GC for these orderings to protect against, but not every back-end can express them: SPIR-V's OpAtomicLoad/OpAtomicStore only take scalar integer or floating-point operands, so the Khronos translator turns anunorderedload of a pointer into an invalid pointer-typed atomic ("AtomicLoad: expected Result Type to be integer or float scalar type" from spirv-val; Intel's compiler fails on an undefined__spirv_AtomicLoad(long**, int, int)). The LLVM SPIR-V back-end already lowers such loads to plain OpLoads. With oneAPI.jl gaining a device allocator, kernels that read boxed fields now reach this on Julia 1.12+.Move the Metal target's
demote_unordered_atomics!next to the other shared post-optimization rewrites and run it from the SPIR-V target'sfinish_ir!too. The end-to-end test compiles anunorderedpointer load and store through both SPIR-V code paths with validation enabled.