---
generated: true
model: claude-opus-4-7
generated_at: 2026-05-22T00:00:00+00:00
source_commit: 6e923e2c0fe3cae4e7cf40e25a96569df5b9f009
watched_paths_digest: 4cd2b0ab91da080eb6a16ece95070e661cf2096b991cd6d164bfccb383236671
source_doc: docs/generated/design/ir-reference/resources-and-atomics.md
source_doc_digest: 3ac0724b29539a4ec7edd0c37f2e44add27803e6c97e8427e2d67a80b87bb345
warning: "Auto-generated. May drift from source. Do not edit by hand."
---

# Tests for ir-reference/resources-and-atomics

## Intent
Tests verify the per-opcode catalog of the IR resource/atomic family
described in
[`docs/generated/design/ir-reference/resources-and-atomics.md`](../../../design/ir-reference/resources-and-atomics.md):
that documented IR opcodes for resource access
(`rwstructuredBufferGetElementPtr`, `rwstructuredBufferLoad`,
`structuredBufferLoad`, `byteAddressBufferLoad`,
`byteAddressBufferStore`, `StructuredBufferAppend`,
`StructuredBufferConsume`, `nonUniformResourceIndex`) and module-
scope shader parameter declarations (`global_param` with various
resource types) surface in IR dumps from natural Slang surfaces, and
that the `Atomic<T>` core-module type lowers each of its methods
(`add`, `min`, `max`, `and`, `or`, `xor`, `exchange`,
`compareExchange`, `load`, `store`) to the corresponding atomic
opcode with a trailing memory-order operand.

Each test compiles to a text-emit target with `-dump-ir
-o /dev/null` so the IR dump goes to stdout uncontaminated by
target text, and uses FileCheck patterns anchored at `func %main`
(for opcodes that surface in user code) or as bare opcode
matchers (for opcodes that live inside the pulled-in library
function bodies of byte-address-buffer accessors).


## Functional coverage
| Claim | Intent | Anchor | Tests |
| --- | --- | --- | --- |
| `AppendStructuredBuffer::Append(v)` lowers to `StructuredBufferAppend(%buf, %v)`; `ConsumeStructuredBuffer::Consume()` lowers to `StructuredBufferConsume(%buf)`. | functional | [#append-and-consume-buffers](../../../design/ir-reference/resources-and-atomics.md#append-and-consume-buffers) | [`append-consume-buffer.slang`](append-consume-buffer.slang) |
| `AppendStructuredBuffer<S>::Append(s)` on a struct element type still lowers to a single `StructuredBufferAppend(%buf, %s)` opcode regardless of element-type shape. | functional | [#append-and-consume-buffers](../../../design/ir-reference/resources-and-atomics.md#append-and-consume-buffers) | [`append-buffer-struct.slang`](append-buffer-struct.slang) |
| `AppendStructuredBuffer<int>::Append(0)` (literal zero element) still surfaces the documented `StructuredBufferAppend(%buf, 0 : Int)` opcode shape. | boundary | [#append-and-consume-buffers](../../../design/ir-reference/resources-and-atomics.md#append-and-consume-buffers) | [`append-buffer-zero-value.slang`](append-buffer-zero-value.slang) |
| `AppendStructuredBuffer<int>::Append(INT_MAX)` (largest signed value) still surfaces the documented `StructuredBufferAppend(%buf, 2147483647 : Int)` opcode shape. | boundary | [#append-and-consume-buffers](../../../design/ir-reference/resources-and-atomics.md#append-and-consume-buffers) | [`append-buffer-int-max-value.slang`](append-buffer-int-max-value.slang) |
| 64 contending threads atomic-adding to a single groupshared `Atomic<int>` still emit a single documented `atomicAdd` opcode in IR. | stress | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-groupshared-contention-numthreads-64.slang`](atomic-groupshared-contention-numthreads-64.slang) |
| 64 contending threads each calling `Atomic<int>::add(1)` on the same element still emit a single documented `atomicAdd` opcode in IR (the contention is a runtime property, not an IR-shape property). | stress | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add-contention-numthreads-64.slang`](atomic-add-contention-numthreads-64.slang) |
| A single thread issuing eight `Atomic<int>::add(...)` calls in sequence emits eight distinct `atomicAdd` opcodes; the IR opcode shape is the same for every call. | stress | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add-many-calls-sequence.slang`](atomic-add-many-calls-sequence.slang) |
| Eight atomic-add calls to eight distinct buffer elements each produce a documented `atomicAdd` opcode; the shape is uniform across operands. | stress | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add-many-distinct-locations-stress.slang`](atomic-add-many-distinct-locations-stress.slang) |
| `Atomic<T>::add(v)` lowers to `atomicAdd(%ptr, %val, %order)`, the IR encoding of the atomic add primitive. | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add.slang`](atomic-add.slang) |
| `Atomic<T>::and(v)` / `or(v)` / `xor(v)` lower to `atomicAnd` / `atomicOr` / `atomicXor` with the standard `(ptr, val, order)` operand shape. | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-bitwise.slang`](atomic-bitwise.slang) |
| `Atomic<T>::exchange(v)` lowers to `atomicExchange(%ptr, %val, %order)`, the swap primitive that returns the previously stored value. | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-exchange.slang`](atomic-exchange.slang) |
| `Atomic<T>::load()` and `::store(v)` lower to the dedicated `atomicLoad(%ptr, %order)` and `atomicStore(%ptr, %val, %order)` opcodes (separate from the RMW ops). | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-load-store.slang`](atomic-load-store.slang) |
| `Atomic<T>::min(v)` and `::max(v)` lower to `atomicMin(%ptr, %val, %order)` and `atomicMax(%ptr, %val, %order)` respectively. | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-min-max.slang`](atomic-min-max.slang) |
| `Atomic<T>` on a `groupshared` array element also lowers to `atomicAdd`, demonstrating that the atomic opcode is independent of the underlying address-space backing the `Atomic<T>` element. | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-groupshared-add.slang`](atomic-groupshared-add.slang) |
| `Atomic<int>::add(0)` (degenerate zero increment) still lowers to the documented `atomicAdd(%ptr, 0 : Int, %order)` opcode shape; constant folding does not remove the call. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add-zero-literal.slang`](atomic-add-zero-literal.slang) |
| `Atomic<int>::add(INT_MAX)` (largest signed value, `2147483647`) still lowers to the documented `atomicAdd` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add-int-max-literal.slang`](atomic-add-int-max-literal.slang) |
| `Atomic<int>::add(INT_MIN)` (smallest signed value, `-2147483648`) still lowers to the documented `atomicAdd` opcode; the negative literal is carried unchanged. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-add-int-min-literal.slang`](atomic-add-int-min-literal.slang) |
| `Atomic<int>::and(0)` (clear-all-bits mask) still lowers to the documented `atomicAnd` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-and-zero-mask.slang`](atomic-and-zero-mask.slang) |
| `Atomic<int>::exchange(0)` (swap-in-zero) still lowers to the documented `atomicExchange` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-exchange-zero.slang`](atomic-exchange-zero.slang) |
| `Atomic<int>::max(INT_MAX)` (degenerate — argument is the absolute maximum) still lowers to the documented `atomicMax` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-max-int-max-literal.slang`](atomic-max-int-max-literal.slang) |
| `Atomic<int>::min(INT_MIN)` (degenerate — argument is the absolute minimum) still lowers to the documented `atomicMin` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-min-int-min-literal.slang`](atomic-min-int-min-literal.slang) |
| `Atomic<int>::store(0)` followed by `::load()` still lowers to the documented `atomicStore(%ptr, 0, ...)` and `atomicLoad(%ptr, ...)` opcode shapes; the zero value is preserved as `0 : Int`. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-load-store-zero.slang`](atomic-load-store-zero.slang) |
| `Atomic<int>::xor(0)` (identity mask) still lowers to the documented `atomicXor` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-xor-zero-mask.slang`](atomic-xor-zero-mask.slang) |
| `Atomic<int>` on a `groupshared` variable with INT_MAX value still lowers to the documented `atomicAdd` opcode shape, independent of address-space. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-groupshared-add-int-max-literal.slang`](atomic-groupshared-add-int-max-literal.slang) |
| `Atomic<uint>::add(0)` (degenerate uint zero) still lowers to the documented `atomicAdd(%ptr, 0 : UInt, %order)` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-uint-add-zero-literal.slang`](atomic-uint-add-zero-literal.slang) |
| `Atomic<uint>::add(UINT_MAX)` (`0xFFFFFFFFu`) still lowers to the documented `atomicAdd` opcode shape with the value carried as `UInt`. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-uint-add-uint-max-literal.slang`](atomic-uint-add-uint-max-literal.slang) |
| `Atomic<uint>::add(v)` lowers to `atomicAdd` exactly as for `int`, with the value typed as `UInt` in the operand position. | functional | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-uint-add.slang`](atomic-uint-add.slang) |
| `Atomic<uint>::or(UINT_MAX)` (set-all-bits mask) still lowers to the documented `atomicOr` opcode shape. | boundary | [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | [`atomic-or-all-bits-mask.slang`](atomic-or-all-bits-mask.slang) |
| `Atomic<T>::compareExchange(expected, desired)` lowers to `atomicCompareExchange(%ptr, %expected, %desired, ...)`, the CAS primitive returning the previous value. | functional | [#atomiccompareexchange](../../../design/ir-reference/resources-and-atomics.md#atomiccompareexchange) | [`atomic-compare-exchange.slang`](atomic-compare-exchange.slang) |
| `Atomic<int>::compareExchange(7, 7)` (matching expected==desired — degenerate CAS) still lowers to the documented `atomicCompareExchange` opcode shape. | boundary | [#atomiccompareexchange](../../../design/ir-reference/resources-and-atomics.md#atomiccompareexchange) | [`atomic-compare-exchange-same-expected-desired.slang`](atomic-compare-exchange-same-expected-desired.slang) |
| `Atomic<int>::compareExchange(INT_MIN, INT_MAX)` (extreme operand pair) still lowers to the documented `atomicCompareExchange` opcode shape; both literals carry through. | boundary | [#atomiccompareexchange](../../../design/ir-reference/resources-and-atomics.md#atomiccompareexchange) | [`atomic-compare-exchange-int-min-int-max.slang`](atomic-compare-exchange-int-min-int-max.slang) |
| Eight consecutive `RWStructuredBuffer::Load(i)` calls each emit a distinct `rwstructuredBufferLoad` opcode; the documented opcode shape repeats. | stress | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`rwstructured-buffer-load-many-loads-stress.slang`](rwstructured-buffer-load-many-loads-stress.slang) |
| `ByteAddressBuffer::Load(0)` (offset 0, lower edge) still surfaces the documented `byteAddressBufferLoad` opcode inside the pulled-in library helper body. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`byte-address-buffer-load-offset-zero.slang`](byte-address-buffer-load-offset-zero.slang) |
| `ByteAddressBuffer::Load(2147483644)` (large 4-byte-aligned offset literal, near INT_MAX) still surfaces the documented `byteAddressBufferLoad` opcode. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`byte-address-buffer-load-large-offset.slang`](byte-address-buffer-load-large-offset.slang) |
| `ByteAddressBuffer::Load(offset)` surfaces the `byteAddressBufferLoad(%buf, %offset, %alignment)` opcode inside the pulled-in library function body for `ByteAddressBuffer.Load`. | functional | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`byte-address-buffer-load.slang`](byte-address-buffer-load.slang) |
| `RWByteAddressBuffer::Store(0, UINT_MAX)` (store the largest unsigned value) still surfaces the documented `byteAddressBufferStore` opcode. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`byte-address-buffer-store-int-max-value.slang`](byte-address-buffer-store-int-max-value.slang) |
| `RWByteAddressBuffer::Store(0, v)` (offset 0, lower edge) still surfaces the documented `byteAddressBufferStore` opcode. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`byte-address-buffer-store-offset-zero.slang`](byte-address-buffer-store-offset-zero.slang) |
| `RWByteAddressBuffer::Store(offset, value)` surfaces the `byteAddressBufferStore(%buf, %offset, %alignment, %value)` opcode inside the pulled-in library function body. | functional | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`byte-address-buffer-store.slang`](byte-address-buffer-store.slang) |
| `RWStructuredBuffer::Load(-1)` (negative signed index) still produces the documented `rwstructuredBufferLoad` opcode shape; the negative literal is carried unchanged as the index operand. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`rwstructured-buffer-load-negative-index-literal.slang`](rwstructured-buffer-load-negative-index-literal.slang) |
| `RWStructuredBuffer::Load(0)` (lower-edge index) still surfaces `rwstructuredBufferLoad(%buf, 0 : Int)` per the documented opcode shape. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`rwstructured-buffer-load-index-zero.slang`](rwstructured-buffer-load-index-zero.slang) |
| `RWStructuredBuffer::Load(INT_MAX)` (largest positive `int` literal) still surfaces the `rwstructuredBufferLoad` opcode with the literal carried as `2147483647 : Int`. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`rwstructured-buffer-load-int-max-literal.slang`](rwstructured-buffer-load-int-max-literal.slang) |
| `RWStructuredBuffer::Load(idx)` surfaces as `rwstructuredBufferLoad(%buf, %idx)`. | functional | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`rwstructured-buffer-load.slang`](rwstructured-buffer-load.slang) |
| `StructuredBuffer::Load(0)` (lower-edge index) still surfaces `structuredBufferLoad(%buf, 0 : Int)`. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`structured-buffer-load-index-zero.slang`](structured-buffer-load-index-zero.slang) |
| `StructuredBuffer::Load(INT_MAX)` (largest positive `int` literal) still surfaces the documented `structuredBufferLoad` opcode. | boundary | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`structured-buffer-load-int-max-literal.slang`](structured-buffer-load-int-max-literal.slang) |
| `StructuredBuffer::Load(idx)` (read-only buffer) surfaces as `structuredBufferLoad(%buf, %idx)`. | functional | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`structured-buffer-load.slang`](structured-buffer-load.slang) |
| `StructuredBuffer::Load(idx, out status)` (the documented status-overload that would surface `structuredBufferLoadStatus`) is rejected with `E36107` on the `compute` stage for `spirv` per the existing doc-gap finding. | negative | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`structured-buffer-load-status-overload-rejected-on-compute-spirv.slang`](structured-buffer-load-status-overload-rejected-on-compute-spirv.slang) |
| `StructuredBuffer<S>::Load(idx)` on a struct element type produces `structuredBufferLoad` returning the struct value; field reads through `get_field` follow. | functional | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`structured-buffer-load-struct.slang`](structured-buffer-load-struct.slang) |
| `rwbuf.Load(idx)` on a `RWStructuredBuffer<float4>` produces `rwstructuredBufferLoad(%buf, %idx)` with a vector result type, demonstrating the variadic-min-2 operand shape. | functional | [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | [`rwstructured-buffer-load-vector.slang`](rwstructured-buffer-load-vector.slang) |
| `CoopMat.MapElement` invoked with an element-wise function surfaces the documented `CoopMatMapElementIFunc` opcode in the IR dump. | functional | [#coopmatmapelementifunc](../../../design/ir-reference/resources-and-atomics.md#coopmatmapelementifunc) | [`coop-mat-map-element.slang`](coop-mat-map-element.slang) |
| `coopMatMulAdd` on three `CoopMat` values surfaces the documented `CoopMatMulAdd` opcode in the IR dump. | functional | [#coopmatmapelementifunc](../../../design/ir-reference/resources-and-atomics.md#coopmatmapelementifunc) | [`coop-mat-mul-add.slang`](coop-mat-mul-add.slang) |
| `coopVecMatMulAdd` on a `CoopVec` with an optional bias surfaces the documented `CoopVecMatMulAdd` opcode in the IR dump. | functional | [#coopmatmapelementifunc](../../../design/ir-reference/resources-and-atomics.md#coopmatmapelementifunc) | [`coop-vec-matmuladd.slang`](coop-vec-matmuladd.slang) |
| `coopVecOuterProductAccumulate` and `coopVecReduceSumAccumulate` surface the documented `CoopVecOuterProductAccumulate` and `CoopVecReduceSumAccumulate` opcodes in the IR dump. | functional | [#coopmatmapelementifunc](../../../design/ir-reference/resources-and-atomics.md#coopmatmapelementifunc) | [`coop-vec-outer-product-and-reduce-sum.slang`](coop-vec-outer-product-and-reduce-sum.slang) |
| A `closesthit` entry point on `-target cuda` with a payload too large for inline registers surfaces the documented `getOptiXRayPayloadPtr` and `getOptiXHitAttribute` opcodes in the IR dump. | functional | [#getoptixraypayloadptr](../../../design/ir-reference/resources-and-atomics.md#getoptixraypayloadptr) | [`optix-ray-payload-closesthit.slang`](optix-ray-payload-closesthit.slang) |
| A small-payload `closesthit` entry point with a uniform shader-record parameter on `-target cuda` surfaces `getOptiXPayloadRegister`, `setOptiXPayloadRegister`, and `getOptiXSbtDataPointer` opcodes in the IR dump. | functional | [#getoptixraypayloadptr](../../../design/ir-reference/resources-and-atomics.md#getoptixraypayloadptr) | [`optix-payload-register-and-sbt.slang`](optix-payload-register-and-sbt.slang) |
| `CallShader(idx, payload)` from a raygeneration entry point on `-target spirv-asm` surfaces the documented `GetVulkanRayTracingPayloadLocation` opcode in the IR dump. | functional | [#getoptixraypayloadptr](../../../design/ir-reference/resources-and-atomics.md#getoptixraypayloadptr) | [`vulkan-raytracing-payload-location.slang`](vulkan-raytracing-payload-location.slang) |
| Indirecting through `DescriptorHandle<T>` on `-target spirv-asm` surfaces the documented `SPIRVLoadDescriptorFromHeap`, `SPIRVResourceHeap`, `SPIRVSamplerHeap`, and `SPIRVLoadTexelPointerFromHeap` opcodes in the IR dump. | functional | [#loadresourcedescriptorfromheap](../../../design/ir-reference/resources-and-atomics.md#loadresourcedescriptorfromheap) | [`descriptor-heap-spirv-load.slang`](descriptor-heap-spirv-load.slang) |
| Indirecting through a `DescriptorHandle<RWStructuredBuffer<T>>` on the HLSL target surfaces the documented `LoadResourceDescriptorFromHeap` opcode in the IR dump. | functional | [#loadresourcedescriptorfromheap](../../../design/ir-reference/resources-and-atomics.md#loadresourcedescriptorfromheap) | [`descriptor-heap-resource-load.slang`](descriptor-heap-resource-load.slang) |
| Indirecting through a `DescriptorHandle<SamplerState>` on the HLSL target surfaces the documented `LoadSamplerDescriptorFromHeap` opcode in the IR dump. | functional | [#loadresourcedescriptorfromheap](../../../design/ir-reference/resources-and-atomics.md#loadresourcedescriptorfromheap) | [`descriptor-heap-sampler-load.slang`](descriptor-heap-sampler-load.slang) |
| A mesh-shader entry point on `-target metal` writes to `out vertices`, `out primitives`, and `out indices` arrays through the documented `metalSetVertex`, `metalSetPrimitive`, and `metalSetIndices` opcodes in the IR dump. | functional | [#meshoutputref](../../../design/ir-reference/resources-and-atomics.md#meshoutputref) | [`mesh-output-metal-set.slang`](mesh-output-metal-set.slang) |
| A mesh-shader entry point that writes to `out vertices`, `out primitives`, and `out indices` arrays surfaces the documented `meshOutputRef` and `meshOutputSet` opcodes in the IR dump. | functional | [#meshoutputref](../../../design/ir-reference/resources-and-atomics.md#meshoutputref) | [`mesh-output-ref-set.slang`](mesh-output-ref-set.slang) |
| `NonUniformResourceIndex(0u)` (lower-edge index literal) still surfaces as `nonUniformResourceIndex(%i)`; the marker is preserved even for constants. | boundary | [#nonuniformresourceindex](../../../design/ir-reference/resources-and-atomics.md#nonuniformresourceindex) | [`non-uniform-resource-index-literal-zero.slang`](non-uniform-resource-index-literal-zero.slang) |
| `NonUniformResourceIndex(0xFFFFFFFFu)` (UINT_MAX literal) still surfaces as `nonUniformResourceIndex(%i)` with the same uint type. | boundary | [#nonuniformresourceindex](../../../design/ir-reference/resources-and-atomics.md#nonuniformresourceindex) | [`non-uniform-resource-index-uint-max-literal.slang`](non-uniform-resource-index-uint-max-literal.slang) |
| `NonUniformResourceIndex(i)` is a no-op at the value level: the operand and result share the same type, so the surrounding indexing expression sees an integer of the same width. | functional | [#nonuniformresourceindex](../../../design/ir-reference/resources-and-atomics.md#nonuniformresourceindex) | [`non-uniform-resource-index-buffer-index.slang`](non-uniform-resource-index-buffer-index.slang) |
| `NonUniformResourceIndex(i)` surfaces as `nonUniformResourceIndex(%i)` — a no-op at the value level whose operand and result share the same type. | functional | [#nonuniformresourceindex](../../../design/ir-reference/resources-and-atomics.md#nonuniformresourceindex) | [`non-uniform-resource-index.slang`](non-uniform-resource-index.slang) |
| Writing `rwbuf[-1] = v` (signed-underflow index literal) still surfaces the documented `rwstructuredBufferGetElementPtr(%base, -1 : Int)` opcode shape. | boundary | [#rwstructuredbuffergetelementptr](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbuffergetelementptr) | [`rwstructured-buffer-getelementptr-negative-index-literal.slang`](rwstructured-buffer-getelementptr-negative-index-literal.slang) |
| Writing `rwbuf[0] = v` (lower-edge index lvalue) still surfaces the documented `rwstructuredBufferGetElementPtr(%base, 0 : Int)` opcode shape. | boundary | [#rwstructuredbuffergetelementptr](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbuffergetelementptr) | [`rwstructured-buffer-getelementptr-index-zero.slang`](rwstructured-buffer-getelementptr-index-zero.slang) |
| Writing `rwbuf[2147483647] = v` (INT_MAX index literal) still surfaces the documented `rwstructuredBufferGetElementPtr` opcode shape; runtime out-of-bounds behavior is undocumented. | boundary | [#rwstructuredbuffergetelementptr](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbuffergetelementptr) | [`rwstructured-buffer-getelementptr-int-max-literal.slang`](rwstructured-buffer-getelementptr-int-max-literal.slang) |
| `rwBuf[i].field = v` surfaces as `rwstructuredBufferGetElementPtr(%base, %i)` followed by `get_field_addr` then `store`, the lvalue counterpart to `rwstructuredBufferLoad`. | functional | [#rwstructuredbuffergetelementptr](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbuffergetelementptr) | [`rwstructured-buffer-getelementptr-nested.slang`](rwstructured-buffer-getelementptr-nested.slang) |
| `rwbuf[i] = vector_expr` for a vector element type also routes through `rwstructuredBufferGetElementPtr` to produce the lvalue, then stores the vector. | functional | [#rwstructuredbuffergetelementptr](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbuffergetelementptr) | [`rwstructured-buffer-vector-element.slang`](rwstructured-buffer-vector-element.slang) |
| `rwbuf[uint_idx] = v` (uint-typed index) still surfaces the documented `rwstructuredBufferGetElementPtr(%base, %index)` opcode shape; the operand type is uint rather than int. | boundary | [#rwstructuredbuffergetelementptr](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbuffergetelementptr) | [`rwstructured-buffer-getelementptr-uint-index.slang`](rwstructured-buffer-getelementptr-uint-index.slang) |
| `Texture1D::Sample(samp, u)` surfaces in `main` as a `call specialize(%Sample, ..., TextureShape1DType, ...)(%tex, %samp, %u)` against the library-level `%Sample` function (the doc's `sample` opcode lives inside the library helper body, not in `main`). | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texture1d-sample-ir.slang`](texture1d-sample-ir.slang) |
| `Texture2D::Gather(samp, uv)` surfaces in `main` as a `call specialize(%Gather, ..., TextureShape2DType, ...)(%tex, %samp, %uv)`. The doc's sampling table catalogs `sample` / `sampleGrad`; `Gather` is part of the same sampling family. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texture2d-gather-ir.slang`](texture2d-gather-ir.slang) |
| `Texture2D::SampleCmp(sampCmp, uv, ref)` with a `SamplerComparisonState` surfaces in `main` as a `call specialize(%SampleCmp, ...)(%tex, %sampCmp, %uv, %ref)`, the comparison-sampler counterpart of the doc's `sample` opcode. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texture2d-samplecmp-sampcmp-ir.slang`](texture2d-samplecmp-sampcmp-ir.slang) |
| `Texture2DArray::Sample(samp, uvw)` surfaces in `main` as a `call specialize(%Sample, ..., TextureShape2DType, 1, ...)` — same shape as `Texture2D` but with the array flag set to 1. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texture2darray-sample-ir.slang`](texture2darray-sample-ir.slang) |
| `Texture3D::Sample(samp, uv)` surfaces in `main` as a `call specialize(%Sample, ..., TextureShape3DType, ...)(%tex, %samp, %uv)` against the library-level `%Sample` function. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texture3d-sample-ir.slang`](texture3d-sample-ir.slang) |
| `TextureCube::Sample(samp, uv)` surfaces in `main` as a `call specialize(%Sample, ..., TextureShapeCubeDType, ...)` against the library helper. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texturecube-sample-ir.slang`](texturecube-sample-ir.slang) |
| `TextureCube::SampleGrad(samp, uv, dx, dy)` surfaces in `main` as a `call specialize(%SampleGrad, ..., TextureShapeCubeDType, ...)(%tex, %samp, %uv, %dx, %dy)` — the explicit-gradient overload of the doc's `sampleGrad` opcode. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texturecube-samplegrad-ir.slang`](texturecube-samplegrad-ir.slang) |
| `TextureCubeArray::Sample(samp, uvwi)` surfaces in `main` as a `call specialize(%Sample, ..., TextureShapeCubeDType, 1, ...)` with the array flag set. | expansion | [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | [`texturecubearray-sample-ir.slang`](texturecubearray-sample-ir.slang) |
| A `ParameterBlock<T>` module-scope parameter surfaces as a `global_param` with type `ParameterBlock(%T)`, and field accesses lower to `get_field_addr` on its `Ptr`. | functional | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`parameter-block-globalparam.slang`](parameter-block-globalparam.slang) |
| A module-scope `ByteAddressBuffer` declaration surfaces a `global_param` with the bare `ByteAddressBuffer` resource type, with no element-type parameter. | functional | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`byte-address-buffer-type-globalparam.slang`](byte-address-buffer-type-globalparam.slang) |
| A module-scope `RWTexture1D<T>` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShape1DType, 0, 0, 0, 1, ...)`, with the read-write access flag set. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`rwtexture1d-globalparam.slang`](rwtexture1d-globalparam.slang) |
| A module-scope `RWTexture3D<T>` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShape3DType, 0, 0, 0, 1, ...)`, combining 3D shape with the RW-access flag. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`rwtexture3d-globalparam.slang`](rwtexture3d-globalparam.slang) |
| A module-scope `SamplerComparisonState` parameter surfaces as a `global_param` with result type `SamplerComparisonState`, distinct from the plain `SamplerState` resource type. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`samplercomparisonstate-globalparam.slang`](samplercomparisonstate-globalparam.slang) |
| A module-scope `Texture1D` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShape1DType, ...)`. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`texture1d-globalparam.slang`](texture1d-globalparam.slang) |
| A module-scope `Texture2DArray` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShape2DType, 1, ...)`, where the `1` is the array-slice flag. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`texture2darray-globalparam.slang`](texture2darray-globalparam.slang) |
| A module-scope `Texture2DMS<T>` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShape2DType, 0, 1, ...)`, with the multi-sample flag set. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`texture2dms-globalparam.slang`](texture2dms-globalparam.slang) |
| A module-scope `Texture3D` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShape3DType, ...)`. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`texture3d-globalparam.slang`](texture3d-globalparam.slang) |
| A module-scope `TextureCubeArray` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShapeCubeDType, 1, ...)`, with the array-slice flag set. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`texturecubearray-globalparam.slang`](texturecubearray-globalparam.slang) |
| A module-scope `TextureCube` parameter surfaces as a `global_param` whose result type is `TextureType(..., TextureShapeCubeDType, ...)`. | expansion | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`texturecube-globalparam.slang`](texturecube-globalparam.slang) |
| Module-scope shader-parameter declarations surface as `global_param` lines in the IR preamble, with the resource type (`RWStructuredBuffer(...)`, `StructuredBuffer(...)`, `ByteAddressBuffer`, `RWByteAddressBuffer`) carried in the result type. | functional | [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | [`structured-buffer-types-globalparam.slang`](structured-buffer-types-globalparam.slang) |
| `RWStructuredBuffer<T>::Load(idx, out status)` on `-target hlsl` surfaces the documented `rwstructuredBufferLoadStatus` opcode in the IR dump. | functional | [#structuredbufferloadstatus](../../../design/ir-reference/resources-and-atomics.md#structuredbufferloadstatus) | [`rwstructured-buffer-load-status-hlsl.slang`](rwstructured-buffer-load-status-hlsl.slang) |
| `StructuredBuffer<T>::Load(idx, out status)` on `-target hlsl` (the capability-permitted target for the status overload) surfaces the documented `structuredBufferLoadStatus` opcode in the IR dump. | functional | [#structuredbufferloadstatus](../../../design/ir-reference/resources-and-atomics.md#structuredbufferloadstatus) | [`structured-buffer-load-status-hlsl.slang`](structured-buffer-load-status-hlsl.slang) |
| `Texture1D::Load(int2(off, lod))` surfaces in `main` as a `call specialize(%Load, ..., TextureShape1DType, ...)(%tex, %coord)`. The doc's `imageLoad` opcode itself lives inside the helper body; only the call form is observable from `main`. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`texture1d-load-ir.slang`](texture1d-load-ir.slang) |
| `Texture2DMS<T>::Load(coord, sampleIndex)` surfaces in `main` as a `call specialize(%Load, ..., TextureShape2DType, ...)(%tex, %coord, %sampleIndex)`, where the `sampleIndex` is passed as a trailing operand to the helper. The MS-ness is carried in the `global_param` texture type, but the `Load`-helper specialization picks the 2D shape token here. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`texture2dms-load-ir.slang`](texture2dms-load-ir.slang) |
| `Texture3D::Load(int4(xyz, lod))` surfaces in `main` as a `call specialize(%Load, ..., TextureShape3DType, ...)(%tex, %coord)`. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`texture3d-load-ir.slang`](texture3d-load-ir.slang) |
| `rwtex[i] = val` assignment on an `RWTexture1D<T>` surfaces in `main` as a `call specialize(..., TextureShape1DType, ..., 1 : Int, ...)(%rwtex, %i, %val)` — the doc's `imageStore` opcode lives inside the helper; the call form is observable from `main`. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`rwtexture1d-store-ir.slang`](rwtexture1d-store-ir.slang) |
| `rwtex[i]` rvalue on an `RWTexture1D<T>` surfaces in `main` as a `call specialize(..., TextureShape1DType, ..., 1 : Int, ...)(%rwtex, %i)` — the doc's `imageSubscript` opcode lives inside the helper; the call form witnesses the 1D + RW combination. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`rwtexture1d-load-ir.slang`](rwtexture1d-load-ir.slang) |
| `rwtex[xyz] = val` assignment on an `RWTexture3D<T>` surfaces in `main` as a `call specialize(..., TextureShape3DType, ...)(%rwtex, %xyz, %val)` — the 3D witness of the doc's `imageStore` opcode in its pre-inline `call` shape. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`rwtexture3d-store-ir.slang`](rwtexture3d-store-ir.slang) |
| `rwtex[xyz]` rvalue on an `RWTexture3D<T>` surfaces in `main` as a `call specialize(..., TextureShape3DType, ...)(%rwtex, %xyz)` — the 3D + RW witness of the doc's `imageSubscript` opcode in its `call`-form pre-inline shape. | expansion | [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | [`rwtexture3d-load-ir.slang`](rwtexture3d-load-ir.slang) |


## Untested claims
| Claim | Reason | Anchor | Why untested |
| --- | --- | --- | --- |
| `atomicSub` — `Atomic<T>` does not expose a `.sub(v)` surface; see doc gaps. | (unclassified) | [#atomicsub](../../../design/ir-reference/resources-and-atomics.md#atomicsub) | Reason and explanation to be refined by the next regeneration. |
| Resource queries and modifier helpers (`getNaturalStride`, `castDynamicResource`, `getEquivalentStructuredBuffer`, `getStructuredBufferPtr`, `getUntypedBufferPtr`, `getRegisterIndex`, `getRegisterSpace`). | (unclassified) | [#getnaturalstride](../../../design/ir-reference/resources-and-atomics.md#getnaturalstride) | Reason and explanation to be refined by the next regeneration. |
| Workgroup / stage introspection (`GetWorkGroupSize`, `GetCurrentStage`) — materialized in the layout / emit pipeline. | (unclassified) | [#getworkgroupsize](../../../design/ir-reference/resources-and-atomics.md#getworkgroupsize) | Reason and explanation to be refined by the next regeneration. |
| Barriers (`GroupMemoryBarrierWithGroupSync`, `ControlBarrier`, `BeginFragmentShaderInterlock`, `EndFragmentShaderInterlock`) — surface as `call` at LOWER-TO-IR. | (unclassified) | [#groupmemorybarrierwithgroupsync](../../../design/ir-reference/resources-and-atomics.md#groupmemorybarrierwithgroupsync) | Reason and explanation to be refined by the next regeneration. |
| Texture and image opcodes (`imageSubscript`, `imageLoad`, `imageStore`, `SubpassLoad`, `MetalCastToDepthTexture`, `IsTextureAccess`, `IsTextureScalarAccess`, `IsTextureArrayAccess`, `ExtractTextureFromTextureAccess`, `ExtractCoordFromTextureAccess`, `ExtractArrayCoordFromTextureAccess`). | (unclassified) | [#imagesubscript](../../../design/ir-reference/resources-and-atomics.md#imagesubscript) | Reason and explanation to be refined by the next regeneration. |
| `MetalAtomicCast`, `IncrementCoverageCounter` — synthesized. | (unclassified) | [#metalatomiccast](../../../design/ir-reference/resources-and-atomics.md#metalatomiccast) | Reason and explanation to be refined by the next regeneration. |
| The doc's `rwstructuredBufferStore` opcode — actually produced via `rwstructuredBufferGetElementPtr` + `store` lowering. | (unclassified) | [#rwstructuredbufferstore](../../../design/ir-reference/resources-and-atomics.md#rwstructuredbufferstore) | Reason and explanation to be refined by the next regeneration. |
| Sampling and combined-sampler opcodes (`sample`, `sampleGrad`, `makeCombinedTextureSampler`, `MakeCombinedTextureSamplerFromHandle`, `CombinedTextureSamplerGetTexture`, `CombinedTextureSamplerGetSampler`). | (unclassified) | [#sample](../../../design/ir-reference/resources-and-atomics.md#sample) | Reason and explanation to be refined by the next regeneration. |
| `StructuredBufferGetDimensions` — appears only inside the helper function body, not on `main`. | (unclassified) | [#structuredbuffergetdimensions](../../../design/ir-reference/resources-and-atomics.md#structuredbuffergetdimensions) | Reason and explanation to be refined by the next regeneration. |
| Wave intrinsics (`waveGetActiveMask`, `waveMaskBallot`, `waveMaskMatch`) — surface as `call` at LOWER-TO-IR. | (unclassified) | [#wavegetactivemask](../../../design/ir-reference/resources-and-atomics.md#wavegetactivemask) | Reason and explanation to be refined by the next regeneration. |


## Doc gaps observed
| Anchor | Kind | Gap | Suggested addition |
| --- | --- | --- | --- |
| [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | undocumented-behavior | The `atomic-operations` table lists `atomicSub` as a distinct opcode, but `Atomic<T>` does not expose a `sub(v)` method on its natural surface — `a.add(-v)` lowers to `atomicAdd(%p, -%v)`, not `atomicSub`. | The doc should either name the AST surface that produces `atomicSub` (perhaps an IR pass that folds `add(-v)` into `sub`) or note that `atomicSub` is synthesized. |
| [#interlockedadd](../../../design/ir-reference/resources-and-atomics.md#interlockedadd) | undocumented-behavior | The doc's HLSL-intrinsic-mapped atomic rows (`InterlockedAdd` → `atomicAdd`, `InterlockedCompareExchange` → `atomicCompareExchange`, etc.) imply the opcodes are produced at LOWER-TO-IR, but in the observed dump the `Interlocked*` intrinsics remain as `call %InterlockedAdd(...)` etc.; only an IR pass later rewrites them to atomic opcodes. The portable surface that does produce the opcodes directly is the `Atomic<T>` core-module type — the doc should mention this surface alongside the HLSL intrinsics. |  |
| [#rwbufi-val-lowering-in-slang-lower-to-ircpp](../../../design/ir-reference/resources-and-atomics.md#rwbufi-val-lowering-in-slang-lower-to-ircpp) | drift-from-source | The `buffer-load-and-store` table lists `rwstructuredBufferStore` with AST origin "`rwBuf[i] = val` lowering in `slang-lower-to-ir.cpp`", but the observed lowering of `rwBuf[i] = val` is `rwstructuredBufferGetElementPtr` followed by `store`, not `rwstructuredBufferStore`. | The doc should either name a different surface that produces `rwstructuredBufferStore` or mark it "(synthesized by an IR pass)". |
| [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | undocumented-behavior | The `buffer-load-and-store` table lists `structuredBufferLoadStatus` / `rwstructuredBufferLoadStatus` produced by the `Load(idx, out status)` overload, but in the `compute` stage on `spirv` the overload is gated behind a capability flag and emits `E36107`. | The doc should either name the required capability or note the overload's gating. |
| [#barriers-and-synchronization](../../../design/ir-reference/resources-and-atomics.md#barriers-and-synchronization) | undocumented-behavior | The `barriers-and-synchronization` row says `GroupMemoryBarrierWithGroupSync` is the opcode produced by the same-named intrinsic, but at LOWER-TO-IR the intrinsic surfaces as `call %GroupMemoryBarrierWithGroupSync()` — the opcode form must appear later in the pipeline. Same observation applies to `ControlBarrier` and `BeginFragmentShaderInterlock` / `EndFragmentShaderInterlock`. |  |
| [#wave-intrinsics](../../../design/ir-reference/resources-and-atomics.md#wave-intrinsics) | undocumented-behavior | The `wave-intrinsics` table similarly lists `waveGetActiveMask` / `waveMaskBallot` / `waveMaskMatch` as the opcodes produced by their same-named intrinsics, but at LOWER-TO-IR they surface as `call %WaveGetActiveMask(...)`. | The doc should clarify the stage at which the call form is rewritten to the opcode form. |
| [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | undocumented-behavior | The `texture-and-image` and `sampling-and-combined-samplers` tables list `imageLoad` / `imageStore` / `imageSubscript` / `sample` / `sampleGrad` as the opcodes produced by `Texture*::Load`, `Texture*::Sample`, `rwtex[uv]`, and `rwtex[uv] = v` respectively. At LOWER-TO-IR the user `main` body hosts a `call specialize(%Load, ...)` / `%Sample` / `%operatorx5Bx5Dx5Fget` / `%operatorx5Bx5Dx5Fset`; the named opcodes live inside those library functions' `GenericAsm` bodies and are not observable from `main`. | The doc should either name the IR pass that inlines and replaces the call with the opcode, or describe the observation method (look inside the library helper body, not main). |
| [#resource-queries-and-modifiers](../../../design/ir-reference/resources-and-atomics.md#resource-queries-and-modifiers) | undocumented-behavior | The `resource-queries-and-modifiers` table lists `StructuredBufferGetDimensions` with AST origin `StructuredBuffer::GetDimensions` method, but the natural surface lowers to a `call %StructuredBufferx5FGetDimensions(...)` on the helper function; the opcode itself appears only inside that helper's body. Same caveat as for the image/sample opcodes above. |  |
| [#buffer-load-and-store](../../../design/ir-reference/resources-and-atomics.md#buffer-load-and-store) | undocumented-behavior | The `buffer-load-and-store` table does not state the runtime behavior of out-of-range buffer indices (one-past-end, negative signed indices, indices larger than the runtime element count). The boundary tests (`*-load-int-max-literal.slang`, `*-load-negative-index-literal.slang`, `*-getelementptr-int-max-literal.slang`, `*-getelementptr-negative-index-literal.slang`) probe these boundaries at the IR-shape level only; runtime semantics (silent ignore / clamp / diagnostic / UB) should be added to the doc. |  |
| [#atomic-operations](../../../design/ir-reference/resources-and-atomics.md#atomic-operations) | undocumented-behavior | The `atomic-operations` table does not state the runtime semantics of integer wrap, saturation, or overflow when the argument to `atomicAdd` / `atomicSub` / `atomicMin` / `atomicMax` drives the stored value past `INT_MIN` / `INT_MAX` / `UINT_MAX`. The boundary tests (`atomic-add-int-min-literal.slang`, `atomic-add-int-max-literal.slang`, `atomic-uint-add-uint-max-literal.slang`, `atomic-min-int-min-literal.slang`, `atomic-max-int-max-literal.slang`) probe IR-shape preservation; runtime semantics should be stated. |  |
| [#member-not-found](../../../design/ir-reference/resources-and-atomics.md#member-not-found) | undocumented-behavior | The `atomic-operations` table does not state which `T` parameters of `Atomic<T>` are supported. In particular, calling `.and(v)` / `.or(v)` / `.xor(v)` on `Atomic<float>` is rejected with `E30027` ("member not found"), but the table does not enumerate which methods exist for which `T`. | The doc should clarify. |
| [#nonuniformresourceindex](../../../design/ir-reference/resources-and-atomics.md#nonuniformresourceindex) | undocumented-behavior | The `nonuniformresourceindex` note states `nonUniformResourceIndex` is a no-op at the value level but does not address whether the opcode is emitted for compile-time-constant operands (e.g. literal `0u`). The boundary tests (`non-uniform-resource-index-literal-zero.slang`, `non-uniform-resource-index-uint-max-literal.slang`) probe this; the doc should clarify whether folding is permitted. |  |
| [#shader-io](../../../design/ir-reference/resources-and-atomics.md#shader-io) | undocumented-behavior | The `shader-io` row mentions `global_param` as the IR form of module-scope shader parameters but does not address resource binding edge cases (`register(u0)`, `register(u<MAX>)`, or conflicting binding declarations). These are not exercised by this bundle. |  |
| [#atomicadd](../../../design/ir-reference/resources-and-atomics.md#atomicadd) | undocumented-behavior | Atomic contention semantics: the doc states `atomicAdd` is the IR form of an atomic add, but does not state how many `atomicAdd` opcodes are emitted from a multi-thread dispatch where many threads add to the same location. Empirically only one opcode is emitted (the parallelism is implicit in the dispatch). | The doc should make this explicit. |
| (unspecified) | undocumented-behavior | The status-overload diagnostic gating in the doc-gap above only applies to `StructuredBuffer::Load(idx, out status)`. The `RWStructuredBuffer::Load(idx, out status)` overload appears not to exist at all (it does not match any overload; the only diagnostic is a use-of-uninitialized warning on the `status` variable), and so its documented opcode `rwstructuredBufferLoadStatus` has no portable Slang surface in this bundle's coverage. |  |
| [#texture-and-image](../../../design/ir-reference/resources-and-atomics.md#texture-and-image) | undocumented-behavior | The `texture-and-image` and `sampling-and-combined-samplers` tables enumerate eight `TextureShape*` carriers (1D / 2D / 3D / Cube, each with optional array, plus 2DMS) and an RW flag on `RWTexture*`. The mapping between those Slang surface types and the IR `TextureShape*Type` tokens (`TextureShape1DType`, `TextureShape2DType`, `TextureShape3DType`, `TextureShapeCubeDType`, plus the trailing array / isMS / isRW operand slots on `TextureType(...)`) is not stated in the doc. Tests in this expansion (`texture*-globalparam.slang`) pin the mapping in IR. |  |
| [#sampling-and-combined-samplers](../../../design/ir-reference/resources-and-atomics.md#sampling-and-combined-samplers) | undocumented-behavior | The doc's `sampling-and-combined-samplers` table lists `sample` and `sampleGrad` but does not enumerate `Gather`, `SampleCmp`, `SampleCmpLevelZero`, `SampleBias`, or `SampleLevel`. All five are documented surfaces on `Texture*` in the core module and all of them lower through the same `call specialize(%helper, ..., TextureShape*Type, ...)` pre-inline shape in `main`. | The doc should either name additional opcodes that correspond to them or note that they share the `sample` / `sampleGrad` opcodes after inlining. |
| [#texture-resident](../../../design/ir-reference/resources-and-atomics.md#texture-resident) | undocumented-behavior | Texture `Load`/`Sample`/`Gather`/`SampleCmp` calls all pass the texture shape, array flag, MS flag, and access flag as specialization arguments to the helper at LOWER-TO-IR, but the isMS slot in the `call specialize(...)` arg list for a `Texture2DMS<T>::Load` is `0`, not `1` — the multi-sample-ness is encoded in the texture's `global_param` type, not re-supplied at the call site. | The doc should state which capability slots are "texture-resident" (only on the type) vs "call-resident" (also passed to the helper specialization). |
| [#samplercomparisonstate](../../../design/ir-reference/resources-and-atomics.md#samplercomparisonstate) | undocumented-behavior | The doc lists `SamplerComparisonState` only implicitly as a variant of `SamplerState`; no row enumerates its distinct IR resource type. The `samplercomparisonstate-globalparam.slang` test pins it as a distinct top-level `global_param` carrier alongside `SamplerState`. |  |
