---
generated: true
model: claude-sonnet-4-6
generated_at: 2026-06-02T09:58:23+00:00
source_commit: 57fb63455095efe1465661001ad147b24b968932
watched_paths_digest: 706c60d950c310f1d589685e53a5bdcadd25f5d0bcf89f803857c5dd27a04dd4
source_doc: docs/language-reference/basics-memory-model-consistency.md
source_doc_digest: 421581b9b57c6fe5cb267dd067dad2ba3e290e98b44b6950bf277c3b6c4c6623
warning: "Auto-generated. May drift from source. Do not edit by hand."
---

# Tests for conformance/basics-memory-model-consistency

## Intent

Tests verify memory consistency claims in the **language reference** at
[`docs/language-reference/basics-memory-model-consistency.md`](../../../../language-reference/basics-memory-model-consistency.md).
The doc defines the Slang memory model: data races, five memory orders (Relaxed, Acquire,
Release, Acquire-Release, Sequentially-Consistent), atomic operations with serialization
and release-acquire semantics, and eight barrier primitives with three address-space scopes
(All, Device, ThreadGroup).

Because runtime memory-ordering guarantees are only observable on a GPU with actual concurrent
threads, the coverage strategy is **emission-first**: SPIRV and HLSL emission tests pin the
atomic ops (`OpAtomicStore`, `OpAtomicLoad`, `OpAtomicIAdd`, etc.) with their memory-semantics
operands, and barrier ops (`OpMemoryBarrier`, `OpControlBarrier`) with their scope and semantics
operands. Two GPU-value claims (atomic total order, release-acquire cross-thread) are authored
as `-dx12` `COMPARE_COMPUTE` tests for CI, marked `ignored` locally.

## Claims

### Preamble / Data Race (`#data-race`)

- **C1**: Two memory accesses _conflict_ if they access overlapping memory locations and at least one is a write.
- **C2**: A memory access conflict is a _data race_ unless: the accesses are by the same thread, OR the accesses are atomic, OR one access happens before the other.
- **C3**: The _happens-before_ relation is established by an atomic load-acquire observing an atomic store-release, memory barriers, or higher-level Slang Standard Library constructs.

### Memory Order (`#memory-order`)

- **C4**: _Relaxed_ memory order — no constraints are imposed on other memory accesses.
- **C5**: _Acquire_ memory order — loads and stores after a load-acquire operation cannot be reordered before the operation.
- **C6**: _Release_ memory order — loads or stores before a store-release operation cannot be reordered after the operation.
- **C7**: _Acquire-Release_ memory order — memory accesses cannot cross an acquire-release operation.
- **C8**: _Sequentially-consistent_ memory order — acquire-release memory order with a sequential total order across all sequentially consistent operations.

### Atomic Memory Access (`#atomics`)

- **C9**: All atomic modifications of a single variable occur in a total order (modifications are serialized).
- **C10**: Relaxed atomic memory access provides no ordering relationship with other memory accesses; only atomicity and variable-local total order are guaranteed.
- **C11**: An atomic store-release to location M followed by a thread observing that store via an atomic load-acquire means the observing thread sees all side effects by the storing thread prior to the store.
- **C12**: Sequentially-consistent ordering implies release-acquire ordering plus a total order across all SeqCst operations.
- **C13**: The Slang standard library provides relaxed atomic operations as global decls (InterlockedAdd, InterlockedMin, InterlockedMax, etc.).
- **C14**: The Slang standard library provides the `Atomic<T>` type for atomic memory access.
- **C15**: Advisory: use only relaxed-memory-order atomics for Slang code targeting multiple backends, since most targets lack native support for other memory ordering semantics.

### Memory Barriers (`#barriers`)

- **C16**: A memory barrier imposes acquire-release reordering constraints: memory accesses before the barrier happen before those after.
- **C17**: There are three address-space scopes for a memory barrier: _All_ (device + thread group), _Device_ (storage buffers and images), _Thread group_ (groupshared memory).
- **C18**: `AllMemoryBarrier()` covers All scope: device and thread group memory accesses.
- **C19**: `AllMemoryBarrierWithGroupSync()` covers All scope with a thread-group synchronization point.
- **C20**: `AllMemoryBarrierWithWaveSync()` covers All scope with a wave-level synchronization point.
- **C21**: `DeviceMemoryBarrier()` covers Device scope: address spaces with all-threads instance scope (storage buffers, images).
- **C22**: `DeviceMemoryBarrierWithGroupSync()` covers Device scope with a thread-group synchronization point.
- **C23**: `GroupMemoryBarrier()` covers Thread group scope: thread group (groupshared) memory accesses.
- **C24**: `GroupMemoryBarrierWithGroupSync()` covers Thread group scope with a thread-group synchronization point.
- **C25**: `GroupMemoryBarrierWithWaveSync()` covers some scope with a wave-level synchronization point (exact scope is a doc gap — see `## Doc gaps observed`).

### General Programming Guidance (`#general-programming-guidance`)

- **C26**: Elect a single thread (first lane) to perform atomic operations to reduce per-thread atomic costs when multiple threads in a warp would otherwise issue redundant atomics.
- **C27**: The recommended pattern: write outputs, call `AllMemoryBarrierWithWaveSync()` to ensure visibility, then use `WaveIsFirstLane()` to elect one thread for the atomic store.

## Functional coverage

| Claim                                                                                                                                                                                                 | Intent     | Anchor                                                                                                                          | Tests                                                                                                                  |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| C4: Relaxed memory order on `Atomic<T>.store` emits `OpAtomicStore` with None (0) memory semantics in SPIRV.                                                                                          | functional | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)                                           | [`atomic-store-relaxed-spirv-emission.slang`](atomic-store-relaxed-spirv-emission.slang)                               |
| C5: Acquire memory order on `Atomic<T>.load` emits `OpAtomicLoad` with Acquire semantics (non-zero, contains Acquire bit) in SPIRV.                                                                   | functional | [#memory-order](../../../../language-reference/basics-memory-model-consistency.md#memory-order)                                 | [`atomic-load-acquire-spirv-emission.slang`](atomic-load-acquire-spirv-emission.slang)                                 |
| C6: Release memory order on `Atomic<T>.store` emits `OpAtomicStore` with Release semantics (68 = UniformMemory\|Release) in SPIRV.                                                                    | functional | [#memory-order](../../../../language-reference/basics-memory-model-consistency.md#memory-order)                                 | [`atomic-store-release-spirv-emission.slang`](atomic-store-release-spirv-emission.slang)                               |
| C7: Acquire-Release memory order on `Atomic<T>.load` emits `OpAtomicLoad` with AcquireRelease semantics (72) in SPIRV. (Note: SPIRV-val rejects this; finding filed.)                                 | functional | [#memory-order](../../../../language-reference/basics-memory-model-consistency.md#memory-order)                                 | [`atomic-acqrel-spirv-emission.slang`](atomic-acqrel-spirv-emission.slang)                                             |
| C9: Atomic modifications are serialized: 64 threads each incrementing by 1 yield exactly 64.                                                                                                          | functional | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)                                           | [`atomic-total-order-gpu-functional.slang`](atomic-total-order-gpu-functional.slang)                                   |
| C10: Relaxed `InterlockedAdd` emits `OpAtomicIAdd` with None (0) semantics in SPIRV and `InterlockedAdd` in HLSL.                                                                                     | functional | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)                                           | [`atomic-add-relaxed-spirv-emission.slang`](atomic-add-relaxed-spirv-emission.slang)                                   |
| C11: Release-acquire cross-thread: thread B observing store-release sees thread A's prior side effects.                                                                                               | functional | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)                                           | [`atomic-release-acquire-cross-thread-gpu-functional.slang`](atomic-release-acquire-cross-thread-gpu-functional.slang) |
| C13: Relaxed atomic global decls (InterlockedMin/Max/And/Or/Xor/Exchange) emit corresponding `OpAtomic*` ops with None semantics in SPIRV and identical intrinsics in HLSL.                           | functional | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)                                           | [`atomic-relaxed-global-decls-spirv-emission.slang`](atomic-relaxed-global-decls-spirv-emission.slang)                 |
| C14: `Atomic<T>` type is available; `.store`/`.load` compile to `OpAtomicStore`/`OpAtomicLoad` in SPIRV.                                                                                              | functional | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)                                           | [`atomic-t-type-available-spirv-emission.slang`](atomic-t-type-available-spirv-emission.slang)                         |
| C16 + C17: Memory barrier provides acquire-release semantics encoded as SequentiallyConsistent in SPIRV memory semantics (bit 8 set).                                                                 | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-acquire-release-semantics-spirv-emission.slang`](barrier-acquire-release-semantics-spirv-emission.slang)     |
| C17: Three scopes produce distinct SPIRV semantics values: All=2376, Device=2120, ThreadGroup=264.                                                                                                    | boundary   | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-scope-distinction-spirv-emission.slang`](barrier-scope-distinction-spirv-emission.slang)                     |
| C18: `AllMemoryBarrier()` emits `OpMemoryBarrier` with Device scope (1) and all-memory semantics (2376) in SPIRV; preserves intrinsic name in HLSL.                                                   | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-all-memory-spirv-emission.slang`](barrier-all-memory-spirv-emission.slang)                                   |
| C19: `AllMemoryBarrierWithGroupSync()` emits `OpControlBarrier` Workgroup(2) Device(1) 2376 in SPIRV; preserves intrinsic name in HLSL.                                                               | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-all-memory-groupsync-spirv-emission.slang`](barrier-all-memory-groupsync-spirv-emission.slang)               |
| C19 vs C18: `*WithGroupSync` emits `OpControlBarrier`; without `GroupSync` emits `OpMemoryBarrier`.                                                                                                   | boundary   | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-groupsync-vs-nongroupsync-spirv-emission.slang`](barrier-groupsync-vs-nongroupsync-spirv-emission.slang)     |
| C20: `AllMemoryBarrierWithWaveSync()` emits `OpControlBarrier` Subgroup(3) Subgroup(3) 2376 in SPIRV.                                                                                                 | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-all-memory-wavesync-spirv-emission.slang`](barrier-all-memory-wavesync-spirv-emission.slang)                 |
| C21: `DeviceMemoryBarrier()` emits `OpMemoryBarrier` Device(1) 2120 in SPIRV; preserves intrinsic name in HLSL.                                                                                       | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-device-memory-spirv-emission.slang`](barrier-device-memory-spirv-emission.slang)                             |
| C22: `DeviceMemoryBarrierWithGroupSync()` emits `OpControlBarrier` Workgroup(2) Device(1) 2120 in SPIRV; preserves intrinsic name in HLSL.                                                            | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-device-memory-groupsync-spirv-emission.slang`](barrier-device-memory-groupsync-spirv-emission.slang)         |
| C23: `GroupMemoryBarrier()` emits `OpMemoryBarrier` Workgroup(2) 264 in SPIRV; preserves intrinsic name in HLSL.                                                                                      | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-group-memory-spirv-emission.slang`](barrier-group-memory-spirv-emission.slang)                               |
| C24: `GroupMemoryBarrierWithGroupSync()` emits `OpControlBarrier` Workgroup(2) Workgroup(2) 264 in SPIRV; preserves intrinsic name in HLSL.                                                           | functional | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)                                         | [`barrier-group-memory-groupsync-spirv-emission.slang`](barrier-group-memory-groupsync-spirv-emission.slang)           |
| C26 + C27: Recommended pattern (write + `AllMemoryBarrierWithWaveSync` + `WaveIsFirstLane` + `Atomic<T>.store`) compiles to `OpGroupNonUniformElect` + `OpControlBarrier` + `OpAtomicStore` in SPIRV. | functional | [#general-programming-guidance](../../../../language-reference/basics-memory-model-consistency.md#general-programming-guidance) | [`guidance-wave-first-lane-pattern-spirv-emission.slang`](guidance-wave-first-lane-pattern-spirv-emission.slang)       |

## Untested claims

| Claim                                                                                                                                                                                 | Reason         | Anchor                                                                                          | Why untested                                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| C1: Two memory accesses conflict if they access overlapping memory locations and at least one is a write.                                                                             | (unclassified) | [#data-race](../../../../language-reference/basics-memory-model-consistency.md#data-race)       | Definitional; the term "conflict" has no independent observable surface in slang-test beyond the data-race definition it supports.                                                                                                           |
| C2 (same-thread non-race): Accesses by the same thread are not a data race.                                                                                                           | (unclassified) | [#data-race](../../../../language-reference/basics-memory-model-consistency.md#data-race)       | Definitional property about program semantics, not a compiler behavioral claim. The compiler does not diagnose or emit differently for same-thread accesses.                                                                                 |
| C2 (atomic non-race): Atomic accesses are not a data race.                                                                                                                            | out-of-bundle  | [#data-race](../../../../language-reference/basics-memory-model-consistency.md#data-race)       | The atomic/non-race property is proven by the total-order tests (C9, C11) which validate the outcome. Independently testing "no race = correct result" requires a GPU runner.                                                                |
| C3: Happens-before from load-acquire observing store-release.                                                                                                                         | out-of-bundle  | [#data-race](../../../../language-reference/basics-memory-model-consistency.md#data-race)       | Covered by C11 (`atomic-release-acquire-cross-thread-gpu-functional.slang`).                                                                                                                                                                 |
| C8: Sequentially-consistent order implies release-acquire plus total order across all SeqCst ops.                                                                                     | gpu-other      | [#memory-order](../../../../language-reference/basics-memory-model-consistency.md#memory-order) | Total ordering across operations from multiple threads requires a GPU runtime with actual concurrent execution. A multi-thread COMPARE_COMPUTE test cannot reliably observe total ordering without a GPU.                                    |
| C12: SeqCst implies release-acquire + total order.                                                                                                                                    | gpu-other      | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)           | As C8 above. Requires concurrent GPU threads.                                                                                                                                                                                                |
| C15: Advisory: prefer relaxed atomics for multi-target code since most targets lack other memory orders.                                                                              | (unclassified) | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)           | An advisory recommendation, not a behavioral claim. The advisory is indirectly supported by the emission tests which show Acquire/Release semantics only compile to non-zero SPIRV semantics (implying they need target support).            |
| C25: `GroupMemoryBarrierWithWaveSync()` covers some scope with wave-level sync.                                                                                                       | (unclassified) | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)         | The doc lists this primitive with a TODO link, providing no scope claim to test. Emission shows it maps to the same SPIRV as `AllMemoryBarrierWithWaveSync`; see `## Doc gaps observed`.                                                     |
| C4/C5/C6/C7 memory-order operands on hlsl/glsl/cuda targets: `Atomic<T>.store/load` with explicit memory order does not preserve the ordering operand on hlsl, glsl, or cuda targets. | (unclassified) | [#memory-order](../../../../language-reference/basics-memory-model-consistency.md#memory-order) | HLSL and GLSL have no per-operation memory-order parameter for structured-buffer atomics; Slang lowers to plain stores/loads. CUDA codegen path also emits plain pointer access for `Atomic<T>.store/load`, discarding the ordering operand. |
| C13 relaxed global decls on wgsl/cpp: `InterlockedAdd/Min/Max/And/Or/Xor/Exchange` not available on wgsl or cpp targets.                                                              | (unclassified) | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)           | Core module gates these intrinsics (`hlsl_glsl_spirv_metal_cuda`) excluding wgsl and cpp. E36107 is emitted.                                                                                                                                 |
| C18–C24 barrier intrinsics on cpp: All barrier primitives (AllMemoryBarrier and siblings) are not available on the cpp target.                                                        | (unclassified) | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)         | Core module capability gate excludes cpp from all GPU-barrier intrinsics (E36107).                                                                                                                                                           |
| C20/C26–C27 AllMemoryBarrierWithWaveSync / WaveIsFirstLane pattern on wgsl/cpp: wave-level sync primitives are not available on wgsl or cpp targets.                                  | (unclassified) | [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)         | Core module capability gate excludes wgsl and cpp from AllMemoryBarrierWithWaveSync (E36107). WGSL has no subgroup/wave-sync surface.                                                                                                        |
| C14 Atomic\<T\>.store/load on cpp: Atomic\<T\> store and load operations are not available on the cpp target.                                                                         | (unclassified) | [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)           | Core module capability gate excludes cpp from Atomic\<T\>.store/.load (E36107).                                                                                                                                                              |

## Doc gaps observed

| Anchor                                                                                          | Kind              | Gap                                                                                                                                                                                                                                                                                                                                                                                                           | Suggested addition                                                                                                                                                                                                                           |
| ----------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [#barriers](../../../../language-reference/basics-memory-model-consistency.md#barriers)         | ambiguous-claim   | `GroupMemoryBarrierWithWaveSync()` is listed as a barrier primitive with a "TODO: link" annotation, giving no indication of its address-space scope (should it cover only thread-group memory, or all memory like `AllMemoryBarrierWithWaveSync`?). Observed SPIRV emission is identical to `AllMemoryBarrierWithWaveSync` (Subgroup scope, all-memory semantics 2376), which contradicts the "Group" naming. | Clarify the address-space scope of `GroupMemoryBarrierWithWaveSync()` and add the missing link. If the scope is All (not Group), rename the function or add a note explaining the naming.                                                    |
| [#memory-order](../../../../language-reference/basics-memory-model-consistency.md#memory-order) | drift-from-source | The doc defines `Acquire-Release` as a valid memory order. Slang accepts `MemoryOrder.AcquireRelease` on a load operation without a diagnostic. However, SPIRV validation rejects the resulting `OpAtomicLoad` with `AcquireRelease` semantics (VUID-10868: "AtomicLoad must not use Release or AcquireRelease memory order"). The SPIRV spec requires loads use only None or Acquire.                        | Add a note that for SPIRV targets, `AcquireRelease` on a load degrades to `Acquire` semantics, or emit a diagnostic warning when `AcquireRelease` is used on a load operation. (Finding: `atomic-load-acqrel-invalid-spirv-semantics.yaml`.) |
| [#atomics](../../../../language-reference/basics-memory-model-consistency.md#atomics)           | missing-example   | The doc mentions the `Atomic<T>` type but does not show a minimal code example of declaring an `RWStructuredBuffer<Atomic<T>>` or calling `.store`/`.load` with explicit `MemoryOrder` arguments. The first code example in the doc uses `Atomic<uint>` only in the guidance section.                                                                                                                         | Add a one- or two-line minimal snippet showing `Atomic<uint>` declaration and `.store`/`.load` with an explicit memory order directly in the `#atomics` section.                                                                             |
