---
gap_intake_report: true
intake_model: claude-opus-5[1m]
intake_at: 2026-08-12T06:44:10Z
target_doc: ir-reference/resources-and-atomics.md
target_doc_source_commit_before: 53b76e6d3009b8e6434d41573524c7ce5c499d23
target_doc_source_commit_after: 67149d1e03ebf1d4645ddd224ff4647a8ea5db53
gap_count: 10
actions:
  fixed: 10
  rejected_bogus: 0
  rejected_out_of_scope: 0
  deferred: 0
  escalated_to_finding: 0
---

# Gap-intake report for ir-reference/resources-and-atomics.md

## Summary

This is a re-run of the gap-intake stage for this page. The previous
cycle fixed seven of ten gaps and deferred three — `f742df1cbf5e`,
`925a5389cc94` and `7ef0acfec3ad` — on the mistaken basis that no
`slangc` was available to try candidate shaders. A native arm64
`slangc` at `build-arm64/Debug/bin/slangc` settles all three, so this
cycle carries the seven earlier verdicts forward verbatim and moves the
three deferrals to `fixed`. The queue is now ten fixed, zero rejected,
zero deferred, zero escalated.

What the compiler showed changed the answers, not just supplied them.
For `f742df1cbf5e` the gap's premise was wrong: a single scalar
entry-point uniform does not fold, it produces the SBT lookup; what
suppresses the lookup is declaring the uniform at module scope, or
using a `compute` stage. For `925a5389cc94` the missing surface turned
out to be a *capability*, `-capability spvDescriptorHeapEXT`, and the
two heap opcodes are core-module intrinsics present from linking
onward rather than things SPIR-V legalization invents, which the table
implied. For `7ef0acfec3ad` the gap's proposed answer (`nointerpolation`
alone) was incomplete: the callable surface is `GetAttributeAtVertex`,
and which of the two opcodes appears is a target decision.

## Actions

| Gap ID       | Action | Evidence                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | Fix summary                                                                                                                     |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| e8a0eb0eafa7 | fixed  | `core.meta.slang:4052-4063` (newly watched) defines `enum MemoryOrder` with each enumerator spliced from the C++ constant — `Relaxed = $(kIRMemoryOrder_Relaxed)` and so on — so the mapping is exact and cannot drift.                                                                                                                                                                                                                                                                                                                                                                                                                                | added the `MemoryOrder.*` spellings under the `IRMemoryOrder` block, noting the splice                                          |
| 972e44de2c38 | fixed  | `hlsl.meta.slang:15532-15533` puts `__intrinsic_op($(kIROp_WaveGetActiveMask))` on `__WaveGetActiveMask()`; the public `WaveGetActiveMask()` at 15538 calls it at 15556.                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | covered by the generalized wrapper section, with the line numbers                                                               |
| b33105c1d0d7 | fixed  | Same pattern: the subscript is the core-module `__ref` accessor, so `rwtex[coord]` is a call until that accessor inlines. Consistent with the `Interlocked*` case the page already documents.                                                                                                                                                                                                                                                                                                                                                                                                                                                         | covered by the generalized wrapper section                                                                                      |
| 0ee661b40073 | fixed  | Same pattern: the opcode is created inside the core-module `GetDimensions` body, not at the call site.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | covered by the generalized wrapper section                                                                                      |
| f5d27f386fc6 | fixed  | Same pattern: the `[ForceInline]` `__target_switch` body is still a call immediately after lowering, so the unused-result `atomicAdd` the paragraph describes appears only after inlining.                                                                                                                                                                                                                                                                                                                                                                                                                                                            | covered by the generalized wrapper section; the "after inlining" qualifier the gap asked for is now the rule the section states |
| a88cfc08a133 | fixed  | Confirmed the honest answer is the gap's second option: no public wrapper exists. `__getEquivalentStructuredBuffer` (`hlsl.meta.slang:10213-10219`) and `__getRegisterIndex` / `__getRegisterSpace` (`26389-26393`) are underscore-prefixed with no ordinary Slang function calling them, unlike `InterlockedAdd`.                                                                                                                                                                                                                                                                                                                                     | added a paragraph after the table stating no public wrapper exists, and that these therefore appear without an inlining step    |
| c797e6b42b45 | fixed  | Interlock surfaces are `beginInvocationInterlock()` / `endInvocationInterlock()` (`core.meta.slang:3538,3543`), matching the opcodes' own `__intrinsic_op` lines at 3537/3542. The HLSL barrier family is at `hlsl.meta.slang:7797, 9943, 11835, 15678, 15713`. `ControlBarrier` genuinely has no spelling.                                                                                                                                                                                                                                                                                                                                            | added a user-surface paragraph after the barrier table, including the fragment-stage requirement                                |
| 925a5389cc94 | fixed  | Re-run, was `deferred`. The switch is a capability, confirmed at `source/slang/hlsl.meta.slang:27797-27803` (`case spvDescriptorHeapEXT:` inside `defaultGetDescriptorFromHandle`, 27708-27807) returning `__spirvLoadDescriptorFromHeap(__spirvResourceHeap()/__spirvSamplerHeap(), i)`; those two are `__intrinsic_op` declarations at 27685/27688. Ran `slangc -dump-ir -target spirv -O0 -capability spvDescriptorHeapEXT -stage compute -entry main` on a shader with `DescriptorHandle<SamplerState>` / `<Texture2D<float4>>`: IR holds `SPIRVLoadDescriptorFromHeap(%34, …)` with `%34 = SPIRVResourceHeap`, `%35 = SPIRVSamplerHeap`; `strings` on the `.spv` gives `SPV_EXT_descriptor_heap`, `slang_resourceHeap`, `slang_samplerHeap`. Dropping the capability gives `GetDynamicResourceHeap` and `__slang_resource_heap` instead. `legalizeIRForSPIRV` is called from `source/slang/slang-emit-spirv.cpp:12131`, after the last `-dump-ir` point, so its two products are not observable there. | named the `DescriptorHandle<T>` + `-capability spvDescriptorHeapEXT` surface after the table, and corrected which producer comes first |
| 7ef0acfec3ad | fixed  | Re-run, was `deferred`. `source/slang/hlsl.meta.slang:11733-11743` shows `GetAttributeAtVertex` is the public surface, with a `__target_switch` whose `hlsl` case uses `__ResolveVaryingInputRef` alone and whose `glsl`/`spirv` case wraps it in `__GetPerVertexInputArray` (intrinsics at 11703 and 11706). Compiling a `fragment` entry point that calls `GetAttributeAtVertex` on a `nointerpolation` input with `-dump-ir -target spirv -O0` yields both opcodes; the same shader on `-target hlsl` yields only `ResolveVaryingInputRef` and emits a `GetAttributeAtVertex` call. The stage requirement is real: `-stage vertex` fails with `error[E36107]: unavailable features in entry point`, citing `GetAttributeAtVertex`. | added a surface paragraph after the Shader IO table naming `GetAttributeAtVertex`, the target split, and the `E36107` stage check |
| f742df1cbf5e | fixed  | Re-run, was `deferred`. The gap's "a single scalar uniform folds" premise is disproved: `slangc -dump-ir -target cuda -stage closesthit -entry ch` on a `closesthit` function with `uniform float scale` shows `let %32 : ConstantBuffer(%ShaderRecordParams, DefaultLayout) = getOptiXSbtDataPointer` in the first dump after `collectOptiXEntryPointUniformParams`, and emits `((ShaderRecordParams_0*)optixGetSbtDataPointer())->scale_0`. The real discriminator is declaration site and stage: the bundle test's module-scope `uniform ShaderRecord sbtRecord` compiles to `globalParams_0->sbtRecord_0` with no SBT access, and a `compute` entry point with a `uniform` parameter emits `__global__ void cs(float scale_0)` — matching the `case Stage::Compute: return;` guard in `source/slang/slang-ir-optix-entry-point-uniforms.cpp` (`processEntryPointImpl`). | added a minimal `closesthit` example under Raytracing payload plus the two shapes that do not produce the opcode                |
