---
generated: true
model: claude-opus-4-7
generated_at: 2026-05-22T00:00:00+00:00
source_commit: 6e923e2c0fe3cae4e7cf40e25a96569df5b9f009
watched_paths_digest: ee6e5a27774a8a9c7ea3024cc5842f7bc1919255c4c0b9751400d25195f0b7bc
source_doc: docs/generated/design/target-pipelines/hlsl.md
source_doc_digest: 2afce914bae96fe2e024bf6b3685b7339df010398abc456d4a58cb329326fa50
warning: "Auto-generated. May drift from source. Do not edit by hand."
---

# Tests for target-pipelines/hlsl

## Intent
Tests verify the HLSL target pipeline described in
[`docs/generated/design/target-pipelines/hlsl.md`](../../../design/target-pipelines/hlsl.md):
the ordered IR-pass sequence run by `linkAndOptimizeIR` and
`emitEntryPointsSourceFromIR` when `CodeGenTarget::HLSL` is
requested, and the HLSL-shaped text the emit phase produces.
The bundle exercises Phase D emit invariants (the
`#pragma pack_matrix(column_major)` prelude header, the
conditional `#ifdef SLANG_HLSL_ENABLE_NVAPI` NVAPI block,
`#line` directives, `register(u|t|b|s N)` resource
annotations, `[numthreads(...)]` entry-point attributes,
`SV_DispatchThreadID` semantic survival, `cbuffer` shape,
struct emission, vector spelling, `groupshared` qualifier
survival, HLSL native `AppendStructuredBuffer` /
`ConsumeStructuredBuffer` retention, and the entry-point name
preservation), plus the HLSL-specific IR-pass effects
(`legalizeNonVectorCompositeSelect`,
`wrapStructuredBuffersOfMatrices` for both matrix-element
StructuredBuffers and cbuffer matrices,
`lowerCombinedTextureSamplers`, `legalizeByteAddressBufferOps`
default options, `legalizeArrayReturnType`, `lowerEnumType`,
`eliminatePhis` default options, atomic-operation survival,
and the HLSL-vs-GLSL non-Khronos contrast). The bundle stops
at HLSL text — DXC, fxc, DXIL, DXBytecode, DXR, and the
fxc-era profile-gated paths are out of scope on the no-GPU
runner.

Coverage strategy: one test per concrete claim in the doc's
Phase A/B/C/D tables that can be observed in
`slangc -target hlsl` text. Default directive is
`//TEST:SIMPLE(filecheck=CHECK):-target hlsl -entry main -stage compute`.
One file (`non-khronos-hlsl-vs-glsl-buffer.slang`) carries a
second `-target glsl` directive because the claim is
specifically about HLSL being non-Khronos.


## Functional coverage
| Claim | Intent | Anchor | Tests |
| --- | --- | --- | --- |
| collectCooperativeMetadata runs when target capabilities imply cooperative_matrix or cooperative_vector; a CoopVec compute kernel under -profile cs_6_9 emits HLSL that retains the cooperative-vector spelling and the byte-address buffer storage backing it. | expansion | [#collectcooperativemetadata](../../../design/target-pipelines/hlsl.md#collectcooperativemetadata) | [`collect-cooperative-metadata-coopvec.slang`](collect-cooperative-metadata-coopvec.slang) |
| DXC is invoked as the downstream compiler when -target dxil is requested; the artifact contains DXIL bytecode whose textual disassembly contains the DXIL entry-point definition. | expansion | [#downstream-dxc-fxc](../../../design/target-pipelines/hlsl.md#downstream-dxc-fxc) | [`downstream-dxc-emits-dxil.slang`](downstream-dxc-emits-dxil.slang) |
| `-target hlsl` stops at HLSL text; no DXIL, no SPIR-V, no bytecode is emitted, only HLSL source. | functional | [#downstream-dxc-fxc](../../../design/target-pipelines/hlsl.md#downstream-dxc-fxc) | [`downstream-stops-at-hlsl-text.slang`](downstream-stops-at-hlsl-text.slang) |
| Stress: five-deep nested if/else still phi-eliminates to a single named local assigned in each leaf. | stress | [#eliminatephis-with-default-options](../../../design/target-pipelines/hlsl.md#eliminatephis-with-default-options) | [`stress-deeply-nested-if-else.slang`](stress-deeply-nested-if-else.slang) |
| eliminatePhis runs with default options on HLSL: an if/else-merged value becomes a named local temporary assigned in each branch. | functional | [#eliminatephis-with-default-options](../../../design/target-pipelines/hlsl.md#eliminatephis-with-default-options) | [`eliminate-phis-default-options.slang`](eliminate-phis-default-options.slang) |
| floatNonUniformResourceIndex runs for HLSL (!isSPIRV); the NonUniformResourceIndex(...) intrinsic survives in the HLSL emission of a fragment-stage bindless texture-array access. | expansion | [#floatnonuniformresourceindex](../../../design/target-pipelines/hlsl.md#floatnonuniformresourceindex) | [`float-non-uniform-resource-index-fragment.slang`](float-non-uniform-resource-index-fragment.slang) |
| Boundary: [vk::binding(N, M)] attributes do not pin HLSL registers — the resource still emits at the positional register(u0). | boundary | [#hlsl-specific-runtime-predicates](../../../design/target-pipelines/hlsl.md#hlsl-specific-runtime-predicates) | [`vk-binding-ignored-on-hlsl.slang`](vk-binding-ignored-on-hlsl.slang) |
| HLSL is non-Khronos: an RWStructuredBuffer is HLSL-shaped (register(uN)) on HLSL but GLSL-shaped (layout buffer) on GLSL. | functional | [#hlsl-specific-runtime-predicates](../../../design/target-pipelines/hlsl.md#hlsl-specific-runtime-predicates) | [`non-khronos-hlsl-vs-glsl-buffer.slang`](non-khronos-hlsl-vs-glsl-buffer.slang) |
| The Vulkan-cross-API option flag -fvk-invert-y enables invertYOfPositionOutput; the IR pass negates the y component of the SV_Position output before the writeback in the emitted target text. | expansion | [#invertyofpositionoutput](../../../design/target-pipelines/hlsl.md#invertyofpositionoutput) | [`invert-y-of-position-output-vertex.slang`](invert-y-of-position-output-vertex.slang) |
| Boundary: ByteAddressBuffer.Load<float>(offset) keeps the float template parameter on HLSL emit. | boundary | [#legalizebyteaddressbufferops-for-hlsl](../../../design/target-pipelines/hlsl.md#legalizebyteaddressbufferops-for-hlsl) | [`byte-address-buffer-load-float.slang`](byte-address-buffer-load-float.slang) |
| Selecting a DX_5_0-or-earlier profile (-profile cs_5_0) sets legalizeByteAddressBufferOps useBitCastFromUInt=true; the fxc-era HLSL emission falls back from Load<T> to asuint/asfloat-style bitcast scaffolding rather than the modern templated method. | expansion | [#legalizebyteaddressbufferops-for-hlsl](../../../design/target-pipelines/hlsl.md#legalizebyteaddressbufferops-for-hlsl) | [`byte-address-buffer-fxc-era-bitcast.slang`](byte-address-buffer-fxc-era-bitcast.slang) |
| legalizeByteAddressBufferOps uses default HLSL options so Load<T> survives as a templated method call. | functional | [#legalizebyteaddressbufferops-for-hlsl](../../../design/target-pipelines/hlsl.md#legalizebyteaddressbufferops-for-hlsl) | [`byte-address-buffer-load-template.slang`](byte-address-buffer-load-template.slang) |
| legalizeEmptyRayPayloadsForHLSL adds a dummy field to an empty DXR ray-payload struct so DXIL has a non-empty payload; the HLSL emission of a closesthit entry point keeps a non-empty payload struct. | expansion | [#legalizeemptyraypayloadsforhlsl](../../../design/target-pipelines/hlsl.md#legalizeemptyraypayloadsforhlsl) | [`legalize-empty-ray-payload-closesthit.slang`](legalize-empty-ray-payload-closesthit.slang) |
| legalizeMeshOutputTypes is gated on reqSet.meshOutput and runs in Phase C for a mesh-stage entry point; the HLSL emission preserves the explicit per-vertex and per-primitive output declarations and the SetMeshOutputCounts call. | expansion | [#legalizemeshoutputtypes](../../../design/target-pipelines/hlsl.md#legalizemeshoutputtypes) | [`legalize-mesh-output-types.slang`](legalize-mesh-output-types.slang) |
| legalizeNonStructParameterToStructForHLSL wraps non-struct DXR-stage parameters in single-field struct types so DXC accepts them; the HLSL emission of an anyhit entry point taking a non-struct payload still produces a struct-typed payload parameter. | expansion | [#legalizenonstructparametertostructforhlsl](../../../design/target-pipelines/hlsl.md#legalizenonstructparametertostructforhlsl) | [`legalize-non-struct-parameter-anyhit.slang`](legalize-non-struct-parameter-anyhit.slang) |
| HLSL-only legalizeNonVectorCompositeSelect rewrites a struct-typed conditional into an explicit if/else with a temporary. | functional | [#legalizenonvectorcompositeselect](../../../design/target-pipelines/hlsl.md#legalizenonvectorcompositeselect) | [`legalize-non-vector-composite-select.slang`](legalize-non-vector-composite-select.slang) |
| Slang's Sampler2D is split by lowerCombinedTextureSamplers into a separable Texture2D + SamplerState pair in HLSL emit. | functional | [#lowercombinedtexturesamplers](../../../design/target-pipelines/hlsl.md#lowercombinedtexturesamplers) | [`lower-combined-texture-sampler.slang`](lower-combined-texture-sampler.slang) |
| lowerEnumType collapses an enum to its underlying integer in HLSL emit; the enumerator name does not survive. | functional | [#phase-a-link-and-entry-point-prep](../../../design/target-pipelines/hlsl.md#phase-a-link-and-entry-point-prep) | [`enum-lowering-to-integer.slang`](enum-lowering-to-integer.slang) |
| Boundary: a standalone ConsumeStructuredBuffer survives HLSL emit with `.Consume()` method intact. | boundary | [#phase-b-specialization-and-type-legalization](../../../design/target-pipelines/hlsl.md#phase-b-specialization-and-type-legalization) | [`consume-structured-buffer-survives.slang`](consume-structured-buffer-survives.slang) |
| Negative: a non-void function missing a return triggers the `checkForMissingReturns` (Phase B, reqSet.missingReturn) diagnostic before HLSL emit. | negative | [#phase-b-specialization-and-type-legalization](../../../design/target-pipelines/hlsl.md#phase-b-specialization-and-type-legalization) | [`missing-return-diag.slang`](missing-return-diag.slang) |
| lowerAppendConsumeStructuredBuffers is skipped for HLSL because HLSL has native Append/Consume types; the type spellings survive. | functional | [#phase-b-specialization-and-type-legalization](../../../design/target-pipelines/hlsl.md#phase-b-specialization-and-type-legalization) | [`append-structured-buffer-survives.slang`](append-structured-buffer-survives.slang) |
| A `static` module-scope variable retains its `static T name = initial;` declaration in HLSL emit. | functional | [#phase-c-hlsl-legalization-lowering-phi-elimination](../../../design/target-pipelines/hlsl.md#phase-c-hlsl-legalization-lowering-phi-elimination) | [`move-global-var-init-to-entry.slang`](move-global-var-init-to-entry.slang) |
| An atomic operation on a UAV survives Phase C (validateAtomicOperations runs for non-SPIRV targets) and emits as the HLSL interlocked intrinsic. | functional | [#phase-c-hlsl-legalization-lowering-phi-elimination](../../../design/target-pipelines/hlsl.md#phase-c-hlsl-legalization-lowering-phi-elimination) | [`atomic-operation-survives.slang`](atomic-operation-survives.slang) |
| Boundary: a scalar `&&` with a side-effecting RHS is lowered into an explicit if/else, preserving short-circuit semantics in the emitted HLSL. | boundary | [#phase-c-hlsl-legalization-lowering-phi-elimination](../../../design/target-pipelines/hlsl.md#phase-c-hlsl-legalization-lowering-phi-elimination) | [`logical-and-short-circuit-side-effect.slang`](logical-and-short-circuit-side-effect.slang) |
| Boundary: a scalar `\|\|` with a side-effecting RHS is lowered into an explicit if/else, preserving short-circuit semantics in the emitted HLSL. | boundary | [#phase-c-hlsl-legalization-lowering-phi-elimination](../../../design/target-pipelines/hlsl.md#phase-c-hlsl-legalization-lowering-phi-elimination) | [`logical-or-short-circuit-side-effect.slang`](logical-or-short-circuit-side-effect.slang) |
| legalizeArrayReturnType rewrites T[N] foo() into void foo(out T[N]) on HLSL because DXC disallows array return values. | functional | [#phase-c-hlsl-legalization-lowering-phi-elimination](../../../design/target-pipelines/hlsl.md#phase-c-hlsl-legalization-lowering-phi-elimination) | [`legalize-array-return-type.slang`](legalize-array-return-type.slang) |
| A RWStructuredBuffer is emitted with register(uN) binding on HLSL. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-u-for-uav.slang`](register-u-for-uav.slang) |
| A SamplerState gets register(sN) on HLSL emit, distinct from t/u/b registers. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-s-for-sampler.slang`](register-s-for-sampler.slang) |
| A cbuffer field group is emitted as a struct declaration followed by a cbuffer block that wraps a field of that struct type on HLSL. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`cbuffer-shape-struct-then-cbuffer.slang`](cbuffer-shape-struct-then-cbuffer.slang) |
| A cbuffer is emitted as cbuffer X : register(bN) { ... } on HLSL. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-b-for-cbuffer.slang`](register-b-for-cbuffer.slang) |
| A compute entry point with [numthreads(X,Y,Z)] survives the pipeline as a [numthreads(X, Y, Z)] HLSL attribute on the entry point function. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`numthreads-attribute-survives.slang`](numthreads-attribute-survives.slang) |
| A groupshared array survives the pipeline as `groupshared T name[N];` on HLSL emit. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`groupshared-memory-survives.slang`](groupshared-memory-survives.slang) |
| A read-only resource (Texture2D, ByteAddressBuffer) is annotated register(tN) in HLSL emit. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-t-for-srv.slang`](register-t-for-srv.slang) |
| A user-declared struct keeps its `struct Name { ... };` shape on HLSL emit (CLikeSourceEmitter convention). | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`struct-declaration-emitted-as-struct.slang`](struct-declaration-emitted-as-struct.slang) |
| Boundary: Texture2D sampled at the (0,0) origin corner emits with SampleLevel(samp, float2(0,0), 0) on HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2d-sample-origin-corner.slang`](texture2d-sample-origin-corner.slang) |
| Boundary: Texture2DMS `.Load(int2(0,0), N-1)` with the largest legal sample index for a 4-sample MSAA texture preserves both the int2 coord and the sample-index argument. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2dms-load-sample-index.slang`](texture2dms-load-sample-index.slang) |
| Boundary: a ConstantBuffer<int> (scalar element) emits as a cbuffer on register(b0) holding a single scalar named after the buffer. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`constant-buffer-scalar-element.slang`](constant-buffer-scalar-element.slang) |
| Boundary: a NaN-producing expression (0.0/0.0) is emitted literally as `(0.0f / 0.0f)` on HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`float-nan-divide.slang`](float-nan-divide.slang) |
| Boundary: a SamplerComparisonState bound `register(s0)` (lower-edge sampler index) preserves its explicit `s0` annotation in HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`samplercmp-explicit-s0.slang`](samplercmp-explicit-s0.slang) |
| Boundary: a SamplerState and a SamplerComparisonState in the same module each take their own `s` register. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture-and-samplercmp-distinct-s-registers.slang`](texture-and-samplercmp-distinct-s-registers.slang) |
| Boundary: a Texture1D bound `register(t0)` (lower-edge index) keeps its explicit `t0` annotation through HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture1d-explicit-register-zero.slang`](texture1d-explicit-register-zero.slang) |
| Boundary: a Texture2DMS<float4, 8> survives HLSL emit with the sample count `8` literally embedded in the type spelling. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2dms-sample-count-eight.slang`](texture2dms-sample-count-eight.slang) |
| Boundary: a Texture3D (SRV) and an RWTexture3D (UAV) in the same module bind to disjoint `t` and `u` register classes. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture3d-and-rwtexture3d-share-binding-space.slang`](texture3d-and-rwtexture3d-share-binding-space.slang) |
| Boundary: a Texture3D bound `register(t127)` (high-index SRV) preserves its explicit `t127` annotation through HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture3d-explicit-t-high-index.slang`](texture3d-explicit-t-high-index.slang) |
| Boundary: a TextureCube<float> (scalar element, not float4) keeps its element-type parameter in the HLSL emit angle brackets. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texturecube-element-float-emit.slang`](texturecube-element-float-emit.slang) |
| Boundary: a cbuffer with a single float4 (vector, not matrix) emits the canonical struct-then-cbuffer pair without matrix wrapping. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`cbuffer-vector-field.slang`](cbuffer-vector-field.slang) |
| Boundary: a negative-zero float literal (-0.0f) is preserved through the emit phase as a distinct bit pattern from +0.0f. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`float-negative-zero-literal.slang`](float-negative-zero-literal.slang) |
| Boundary: a positive-infinity-producing expression (1.0/0.0) is emitted literally as `(1.0f / 0.0f)` on HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`float-positive-infinity-divide.slang`](float-positive-infinity-divide.slang) |
| Boundary: a void entry-point body with no statements emits a syntactically valid `void main(...)` { } in HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`empty-function-body-emit.slang`](empty-function-body-emit.slang) |
| Boundary: an RWTexture1D bound `register(u63)` (high-index UAV) preserves its explicit `u63` annotation through HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`rwtexture1d-explicit-u-high-index.slang`](rwtexture1d-explicit-u-high-index.slang) |
| Boundary: an RWTexture3D bound `register(u0)` (lower-edge UAV index) preserves its explicit `u0` annotation through HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`rwtexture3d-explicit-u0.slang`](rwtexture3d-explicit-u0.slang) |
| Boundary: an SRV Texture2D and an UAV RWTexture2D coexist; they bind to `t` and `u` register classes respectively. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`rwtexture-and-srv-texture-distinct-registers.slang`](rwtexture-and-srv-texture-distinct-registers.slang) |
| Boundary: an explicit cs_6_0 (lowest documented SM 6.x compute profile) still emits the canonical HLSL prelude pack_matrix(column_major). | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`profile-cs-6-0-emits-prelude.slang`](profile-cs-6-0-emits-prelude.slang) |
| Boundary: an explicit cs_6_8 (highest documented SM 6.x compute profile) still emits the canonical HLSL prelude pack_matrix(column_major). | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`profile-cs-6-8-emits-prelude.slang`](profile-cs-6-8-emits-prelude.slang) |
| Boundary: even when the shader uses NO NV intrinsic, the prelude still emits the SLANG_HLSL_ENABLE_NVAPI guard for nvHLSLExtns.h. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`nvapi-guard-present-without-nv-intrinsic.slang`](nvapi-guard-present-without-nv-intrinsic.slang) |
| Boundary: even with a wave intrinsic (WaveActiveSum) in the kernel, the prelude still emits the SLANG_HLSL_ENABLE_NVAPI guard — it does not switch to an unconditional include. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`nvapi-guard-with-wave-intrinsic.slang`](nvapi-guard-with-wave-intrinsic.slang) |
| Boundary: float largest-finite (3.402823e+38f) is emitted in scientific notation on HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`float-largest-finite.slang`](float-largest-finite.slang) |
| Boundary: float smallest positive subnormal (~1.4e-45f) survives the emitter as a scientific-notation literal. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`float-smallest-subnormal.slang`](float-smallest-subnormal.slang) |
| Boundary: int MAX (2147483647) is emitted as the decimal literal `2147483647` on HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`int-literal-max-emits-decimal.slang`](int-literal-max-emits-decimal.slang) |
| Boundary: int MIN (-2147483648) is emitted as the decimal literal wrapped in int(...) cast on HLSL. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`int-literal-min-emits-decimal.slang`](int-literal-min-emits-decimal.slang) |
| Boundary: integer vectors keep their HLSL spelling `int<N>`, not GLSL's `ivec<N>` or WGSL's `vec<N><i32>`. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`int-vector-keeps-hlsl-spelling.slang`](int-vector-keeps-hlsl-spelling.slang) |
| Boundary: largest fixed-width vector (float4) is spelled `float4` in HLSL emit, distinct from GLSL `vec4`. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`vector-float4-largest-dim.slang`](vector-float4-largest-dim.slang) |
| Boundary: numthreads with the maximum-documented Y dimension (1024) survives to the HLSL attribute. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`numthreads-y-max-1024.slang`](numthreads-y-max-1024.slang) |
| Boundary: three textures of different shape (1D / 3D / Cube) bind to consecutive `t` registers when used in the same module. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`multiple-textures-distinct-t-registers.slang`](multiple-textures-distinct-t-registers.slang) |
| Boundary: uint MAX (0xFFFFFFFF) is emitted as the decimal-U literal `4294967295U` in HLSL text. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`uint-literal-max-emits-decimal-u.slang`](uint-literal-max-emits-decimal-u.slang) |
| Boundary: uint zero is emitted as `0U` in HLSL text. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`uint-literal-zero.slang`](uint-literal-zero.slang) |
| ConstantBuffer<T> at module scope emits as cbuffer X : register(bN) in HLSL. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`constant-buffer-emits-as-cbuffer.slang`](constant-buffer-emits-as-cbuffer.slang) |
| Expansion: Texture2D `.GatherGreen(samp, uv)` survives HLSL emit verbatim (per-channel gather variant). | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2d-gathergreen-emit.slang`](texture2d-gathergreen-emit.slang) |
| Expansion: Texture2D `.GatherRed(samp, uv)` survives HLSL emit verbatim alongside the Texture2D / SamplerState pair. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2d-gatherred-emit.slang`](texture2d-gatherred-emit.slang) |
| Expansion: Texture2D `.SampleGrad(samp, uv, ddx, ddy)` survives HLSL emit with the float2 coord and gradient pair. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2d-samplegrad-emit.slang`](texture2d-samplegrad-emit.slang) |
| Expansion: Texture2DArray `.Load(int4)` survives HLSL emit (int4 = xy + slice + mip). | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2darray-load-emit.slang`](texture2darray-load-emit.slang) |
| Expansion: Texture3D `.SampleLevel(samp, float3, lod)` rides through HLSL emit with the float3 coord literal preserved. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture3d-samplelevel-emit.slang`](texture3d-samplelevel-emit.slang) |
| Expansion: TextureCube `.SampleGrad(samp, dir, ddx, ddy)` survives HLSL emit with the SampleGrad spelling and the TextureCube native type. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texturecube-samplegrad-emit.slang`](texturecube-samplegrad-emit.slang) |
| Expansion: `tex.SampleCmpLevelZero(sampCmp, uv, ref)` survives HLSL emit with the explicit-LOD-zero compare-sample call name preserved. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`samplercmp-samplecmplevelzero-emit.slang`](samplercmp-samplecmplevelzero-emit.slang) |
| Expansion: a SamplerComparisonState binds to an `s` register and `tex.SampleCmp(sampCmp, uv, ref)` survives HLSL emit verbatim. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`samplercmp-emit.slang`](samplercmp-emit.slang) |
| Expansion: a Slang `break` inside a loop is emitted as a `break` (or equivalent loop exit) in HLSL. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`break-in-loop-emit.slang`](break-in-loop-emit.slang) |
| Expansion: a Slang `continue` inside a for-loop is emitted as a recognisable continue-equivalent in HLSL. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`continue-in-loop-emission.slang`](continue-in-loop-emission.slang) |
| Expansion: a Slang do-while loop is emitted as an HLSL loop with a tail conditional branch by the shared C-like emitter. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`do-while-loop-statement-emission.slang`](do-while-loop-statement-emission.slang) |
| Expansion: a Slang for-loop is emitted as an HLSL `for(...)` statement by the shared C-like emitter. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`for-loop-statement-emission.slang`](for-loop-statement-emission.slang) |
| Expansion: a Slang switch is emitted as an HLSL `switch`/`case` statement by the shared C-like emitter. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`switch-case-statement-emission.slang`](switch-case-statement-emission.slang) |
| Expansion: a Slang while-loop is emitted as an HLSL loop with a header conditional branch by the shared C-like emitter. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`while-loop-statement-emission.slang`](while-loop-statement-emission.slang) |
| Expansion: a Texture1D `.Load(int2)` call survives HLSL emit as the same method spelling. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture1d-load-emit.slang`](texture1d-load-emit.slang) |
| Expansion: a Texture1D resource keeps its HLSL spelling and lands in a `t` register on HLSL emit. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture1d-emit.slang`](texture1d-emit.slang) |
| Expansion: a Texture2D `.Sample(samp, uv)` (no explicit LOD) survives HLSL emit; the Sample variant is the implicit-derivatives form. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2d-sample-emit.slang`](texture2d-sample-emit.slang) |
| Expansion: a Texture2DArray resource keeps its HLSL spelling and lands in a `t` register; SampleLevel takes a float3 coord (uv + slice). | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2darray-emit.slang`](texture2darray-emit.slang) |
| Expansion: a Texture2DMS<float4, N> resource keeps its native HLSL spelling with the sample count in the type angle brackets. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture2dms-emit.slang`](texture2dms-emit.slang) |
| Expansion: a Texture3D `.Load(int4)` call survives HLSL emit with the native Texture3D spelling and `t` register. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture3d-emit.slang`](texture3d-emit.slang) |
| Expansion: a Texture3D resource keeps its HLSL spelling and lands in a `t` register on HLSL emit. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texture3d-sample-emit.slang`](texture3d-sample-emit.slang) |
| Expansion: a TextureCube resource keeps its HLSL spelling and lands in a `t` register on HLSL emit. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texturecube-sample-emit.slang`](texturecube-sample-emit.slang) |
| Expansion: a TextureCubeArray resource keeps its HLSL spelling and lands in a `t` register on HLSL emit. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`texturecubearray-emit.slang`](texturecubearray-emit.slang) |
| Expansion: a local fixed-size array declaration is emitted as `T name[N];` in HLSL. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`local-array-declaration-emit.slang`](local-array-declaration-emit.slang) |
| Expansion: a struct that contains another user struct as a field is emitted with both struct declarations preserved on HLSL. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`struct-nested-fields-emit.slang`](struct-nested-fields-emit.slang) |
| Expansion: a user-defined helper function emits as a `RetType name_<N>(args) { ... }` declaration in HLSL. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`function-call-user-defined-emit.slang`](function-call-user-defined-emit.slang) |
| Expansion: a vector swizzle (.xy) survives the pipeline as `.xy` in HLSL emit text. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`vector-swizzle-xyzw-emit.slang`](vector-swizzle-xyzw-emit.slang) |
| Expansion: an RWTexture1D resource is written and read via the subscript operator; HLSL emit retains the RWTexture1D type and binds it to a `u` register. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`rwtexture1d-emit.slang`](rwtexture1d-emit.slang) |
| Expansion: an RWTexture2D is written and read via uint2 subscript; HLSL emit preserves the native RWTexture2D spelling and `u` register. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`rwtexture2d-emit.slang`](rwtexture2d-emit.slang) |
| Expansion: an RWTexture3D is written and read via the uint3 subscript; HLSL emit retains the RWTexture3D type and binds it to a `u` register. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`rwtexture3d-emit.slang`](rwtexture3d-emit.slang) |
| Expansion: an explicit float-to-int cast is emitted as the HLSL constructor-style `int(...)` form. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`cast-constructor-style-emit.slang`](cast-constructor-style-emit.slang) |
| Expansion: an explicit uint-to-float cast is emitted as the HLSL constructor-style `float(...)` form. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`cast-uint-to-float-emit.slang`](cast-uint-to-float-emit.slang) |
| Expansion: bit-shift operators `<<` and `>>` on uniform operands emit as the HLSL spellings. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`expression-shift-operators-emit.slang`](expression-shift-operators-emit.slang) |
| Expansion: bitwise & / \| / ^ on uniform integer operands emit as the HLSL spellings. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`expression-bitwise-operators-emit.slang`](expression-bitwise-operators-emit.slang) |
| Expansion: emitter spells `*` and `+` binary expressions on uniform operands directly in HLSL text. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`expression-binary-precedence-emit.slang`](expression-binary-precedence-emit.slang) |
| Expansion: unary negate on a uniform integer emits as `-` in HLSL text. | expansion | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`expression-unary-negate-emit.slang`](expression-unary-negate-emit.slang) |
| HLSL emit begins with the #pragma pack_matrix(column_major) directive so matrix layout is deterministic. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`prelude-pack-matrix-pragma.slang`](prelude-pack-matrix-pragma.slang) |
| HLSL emit spells vectors in HLSL form (`float3`/`float4`) — not GLSL's `vec3` and not WGSL's `vec3<f32>`. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`float-vector-keeps-hlsl-spelling.slang`](float-vector-keeps-hlsl-spelling.slang) |
| HLSL emit wraps the nvHLSLExtns.h include behind #ifdef SLANG_HLSL_ENABLE_NVAPI so it is opt-in. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`prelude-nvapi-include-conditional.slang`](prelude-nvapi-include-conditional.slang) |
| Lower-edge boundary: [numthreads(1,1,1)] is emitted exactly with all three dimensions equal to one. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`numthreads-one-one-one.slang`](numthreads-one-one-one.slang) |
| Lower-edge boundary: a SamplerState pinned to register(s0) emits exactly that binding (not renumbered). | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-s-explicit-zero.slang`](register-s-explicit-zero.slang) |
| Lower-edge boundary: a Texture2D pinned to register(t0) emits exactly that binding. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-t-explicit-zero.slang`](register-t-explicit-zero.slang) |
| Lower-edge boundary: a cbuffer pinned to register(b0) emits exactly that binding. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-b-explicit-zero.slang`](register-b-explicit-zero.slang) |
| Lower-edge boundary: an RWStructuredBuffer pinned to register(u0) emits exactly that binding (not renumbered). | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-u-explicit-zero.slang`](register-u-explicit-zero.slang) |
| Multiple unbound UAVs get sequentially numbered register(uN) annotations on HLSL emit. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`multiple-resources-distinct-registers.slang`](multiple-resources-distinct-registers.slang) |
| Negative: [numthreads(0,1,1)] is rejected at check time with an "expected a positive integer" diagnostic. | negative | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`numthreads-zero-rejected-diag.slang`](numthreads-zero-rejected-diag.slang) |
| Negative: an unknown profile string (cs_99_99) is rejected on the command line with an "unknown profile" diagnostic. | negative | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`profile-unknown-rejected-diag.slang`](profile-unknown-rejected-diag.slang) |
| Negative: two RWStructuredBuffers explicitly bound to the same register(u0) trigger an explicit-binding-overlap diagnostic. | negative | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-conflicting-bindings-diag.slang`](register-conflicting-bindings-diag.slang) |
| Smallest-shape boundary: a cbuffer with a single scalar field still emits the canonical struct-then-cbuffer pair. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`cbuffer-single-scalar.slang`](cbuffer-single-scalar.slang) |
| Stress: a cbuffer with many mixed-type fields and a matrix still emits as a single parameter-group struct followed by a cbuffer block. | stress | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`cbuffer-many-mixed-fields.slang`](cbuffer-many-mixed-fields.slang) |
| Stress: a fixed-size array of eight RWStructuredBuffers consumes register slots u0..u7 and the trailing scalar UAV gets u8. | stress | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`stress-resource-array-eight-uavs.slang`](stress-resource-array-eight-uavs.slang) |
| Stress: a helper function with eight scalar parameters emits with all parameters preserved on HLSL. | stress | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`stress-many-function-parameters.slang`](stress-many-function-parameters.slang) |
| Stress: a switch with eight case arms emits as a single HLSL `switch` with all arms preserved. | stress | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`stress-many-case-switch.slang`](stress-many-case-switch.slang) |
| Stress: every control-flow path returns explicitly; the emitter still produces a single void main entry point. | stress | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`stress-all-paths-return.slang`](stress-all-paths-return.slang) |
| Stress: five-deep nested for-loops are emitted as five nested HLSL `for(...)` statements by the shared C-like emitter. | stress | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`stress-deeply-nested-for-loops.slang`](stress-deeply-nested-for-loops.slang) |
| The HLSL entry point function name is the user's entry-point name; HLSL emit does not rename main. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`entry-point-name-main-preserved.slang`](entry-point-name-main-preserved.slang) |
| The SV_DispatchThreadID system-value semantic on a compute-stage input parameter survives the pipeline and appears on the HLSL entry point parameter list. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`sv-dispatch-thread-id-survives.slang`](sv-dispatch-thread-id-survives.slang) |
| The SourceWriter emits #line N "source" directives in HLSL emit so DXC can map errors back. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`sourcewriter-emits-line-directives.slang`](sourcewriter-emits-line-directives.slang) |
| The SourceWriter emits #line directives that reference both the user .slang file and the core/HLSL meta-modules when emitted code originates from there. | functional | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`line-directive-references-core-meta.slang`](line-directive-references-core-meta.slang) |
| Upper-edge boundary: [numthreads(1024,1,1)] is emitted exactly (HLSL documented per-dim max for the X dimension). | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`numthreads-max-x-1024.slang`](numthreads-max-x-1024.slang) |
| Upper-edge boundary: a high explicit register(b14) for a cbuffer is preserved literally on HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-b-explicit-high-index.slang`](register-b-explicit-high-index.slang) |
| Upper-edge boundary: a high explicit register(s31) for a SamplerState is preserved literally on HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-s-explicit-high-index.slang`](register-s-explicit-high-index.slang) |
| Upper-edge boundary: a high explicit register(t63) for a Texture2D is preserved literally on HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-t-explicit-high-index.slang`](register-t-explicit-high-index.slang) |
| Upper-edge boundary: a high explicit register(u99) is preserved literally on HLSL emit. | boundary | [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | [`register-u-explicit-high-index.slang`](register-u-explicit-high-index.slang) |
| A row_major matrix in a cbuffer is rewritten into a _MatrixStorage_<spelling>natural_<N> struct on HLSL emit. | functional | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`row-major-matrix-storage-struct.slang`](row-major-matrix-storage-struct.slang) |
| Boundary: a 2x2 matrix element type in a structured buffer is still wrapped into a single-field struct, distinct from the 4x4 baseline. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`wrap-structured-buffer-of-half-matrix.slang`](wrap-structured-buffer-of-half-matrix.slang) |
| Boundary: a StructuredBuffer<float> with a scalar (non-matrix) element type does NOT trigger the wrapper-struct rewrite. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`structured-buffer-of-float-no-wrap.slang`](structured-buffer-of-float-no-wrap.slang) |
| Boundary: a column_major matrix in a cbuffer does NOT need a _MatrixStorage_ wrapper because it matches the prelude pack_matrix(column_major) default. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`cbuffer-column-major-matrix.slang`](cbuffer-column-major-matrix.slang) |
| Boundary: a function parameter typed `inout row_major float4x4` carries the row_major qualifier through to the emitted HLSL function signature. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`row-major-inout-function-param.slang`](row-major-inout-function-param.slang) |
| Boundary: a matrix declared in a cbuffer without a row_major/column_major qualifier emits as plain `float4x4` under the default column_major pragma. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`cbuffer-default-matrix-no-qualifier.slang`](cbuffer-default-matrix-no-qualifier.slang) |
| Boundary: a user-struct element type in a structured buffer is not wrapped, because the element is already a struct. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`structured-buffer-of-user-struct-no-wrap.slang`](structured-buffer-of-user-struct-no-wrap.slang) |
| Boundary: an `RWStructuredBuffer<float4>` element is a vector — NOT a matrix — so wrapStructuredBuffersOfMatrices does not wrap it. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`structured-buffer-of-vector-no-wrap.slang`](structured-buffer-of-vector-no-wrap.slang) |
| Boundary: an array-of-row_major-matrix field in a cbuffer still produces the standard SLANG_ParameterGroup struct shape. | boundary | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`cbuffer-array-of-row-major-matrix.slang`](cbuffer-array-of-row-major-matrix.slang) |
| Stress: a StructuredBuffer<double4x4> (largest documented matrix dim, 64-bit element) still triggers the single-field wrapper struct rewrite. | stress | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`stress-structured-buffer-of-double-matrix.slang`](stress-structured-buffer-of-double-matrix.slang) |
| wrapStructuredBuffersOfMatrices does NOT wrap a non-matrix element type; a StructuredBuffer<int> stays as RWStructuredBuffer<int>. | functional | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`structured-buffer-of-int-no-wrap.slang`](structured-buffer-of-int-no-wrap.slang) |
| wrapStructuredBuffersOfMatrices wraps a matrix-typed StructuredBuffer element in a single-field struct so pack_matrix applies. | functional | [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | [`wrap-structured-buffer-of-matrix.slang`](wrap-structured-buffer-of-matrix.slang) |


## Untested claims
| Claim | Reason | Anchor | Why untested |
| --- | --- | --- | --- |
| **`autodiff` / `higherOrderFunc` passes** (`checkAutodiffPatterns`, `specializeHigherOrderParameters`, `finalizeAutoDiffPass`, etc.). The doc anchors them to Phase B but the emit-stage observable is a downstream language feature; covered by other bundles. | (unclassified) | [#autodiff](../../../design/target-pipelines/hlsl.md#autodiff) | Reason and explanation to be refined by the next regeneration. |
| **`coverageTracing`-gated passes** (`instrumentCoverage`, `finalizeCoverageInstrumentationMetadata`). Coverage instrumentation is a debugging flag, not user-observable through text emit. | (unclassified) | [#coveragetracing](../../../design/target-pipelines/hlsl.md#coveragetracing) | Reason and explanation to be refined by the next regeneration. |
| **`dynamicResourceHeap`**. | (unclassified) | [#dynamicresourceheap](../../../design/target-pipelines/hlsl.md#dynamicresourceheap) | Requires the SM 6.6 dynamic resource heap setup. |
| **`legalizeUniformBufferLoad`** (`#legalizeuniformbufferload`). The doc anchors it as an IR-level canonicalization without naming an emit marker. | (unclassified) | [#legalizeuniformbufferload](../../../design/target-pipelines/hlsl.md#legalizeuniformbufferload) | Reason and explanation to be refined by the next regeneration. |
| **Pass-ordering claims** (Phase A passes 1-20, Phase B passes 1-63, Phase C passes 1-31). The doc enumerates the ordered list; pass _existence_ is observable through emit side effects, but pass _ordering_ would require `-dump-ir` cross-pass comparison without doc-anchored ordering markers. Covered by `pipeline/05-ir-passes`. | implementation-detail | (unspecified) | Internal compiler choice (pass ordering, hoistability decisions, deduplication) with no test-directive that reveals it. |


## Doc gaps observed
| Anchor | Kind | Gap | Suggested addition |
| --- | --- | --- | --- |
| [#pragma](../../../design/target-pipelines/hlsl.md#pragma) | undocumented-behavior | The doc's Phase D table mentions the `HLSLSourceEmitter` and the emit step but does not name `#pragma pack_matrix(column_major)` as the canonical HLSL prelude marker, or describe the `#ifdef SLANG_HLSL_ENABLE_NVAPI` guarded `nvHLSLExtns.h` include. | A one-line statement of these two emit-prelude facts would let a test anchor them precisely; this bundle anchors them to the general `#phase-d-hlsl-emit-and-downstream-tools` section. |
| [#wrapstructuredbuffersofmatrices](../../../design/target-pipelines/hlsl.md#wrapstructuredbuffersofmatrices) | undocumented-behavior | The doc's `## wrapStructuredBuffersOfMatrices` section describes wrapping the matrix element of a `StructuredBuffer` but does not state the emit-time naming convention (`_S<N>` for the wrapper struct, `_MatrixStorage_<spelling>natural_<N>` for the storage form picked up via `cbuffer` with `row_major`). Documenting these names would let a test pin the exact spelling rather than a regex; this bundle uses regex wildcards. |  |
| [#legalizeuniformbufferload](../../../design/target-pipelines/hlsl.md#legalizeuniformbufferload) | undocumented-behavior | The doc does not state that `legalizeUniformBufferLoad` is observable through any specific HLSL emit pattern. We have no test for it because the doc does not anchor a checkable marker. |  |
| [#legalizelogicalandor](../../../design/target-pipelines/hlsl.md#legalizelogicalandor) | undocumented-behavior | The doc's `## legalizeLogicalAndOr` notes that DXC short-circuits `&&` / `\|\|` on scalars only, and that the IR pass rewrites short-circuit ops over vectors. The doc does not specify what the emitted text looks like in the rewritten form (e.g. element-wise `select` calls vs. preserved `&&` on vectors that the underlying HLSL accepts). We do not test this claim because the emit-side observation is not pinned by the doc. |  |
| [#floatnonuniformresourceindex](../../../design/target-pipelines/hlsl.md#floatnonuniformresourceindex) | undocumented-behavior | The doc's `## floatNonUniformResourceIndex` mentions the `NonUniformResourceIndex(...)` HLSL intrinsic but does not give a Slang-language way to surface it on a compute-stage entry point. The natural surface is a graphics-pipeline bindless workflow; this bundle now exercises it via a fragment-stage test. | Add a Slang-language surface section that shows the `NonUniformResourceIndex(idx)` index-wrapper idiom on at least one pipeline-stage example (fragment or compute) and links to it from the table row. |
| [#adddenormalmodedecorations](../../../design/target-pipelines/hlsl.md#adddenormalmodedecorations) | undocumented-behavior | The doc's Phase A table lists `addDenormalModeDecorations` as always-on, but does not state any user-observable HLSL emit marker for denormal mode. No test. |  |
| [#applyvariablescopecorrection](../../../design/target-pipelines/hlsl.md#applyvariablescopecorrection) | undocumented-behavior | The doc lists `applyVariableScopeCorrection` as running for HLSL but does not name an observable emit pattern (HLSL scoping is implicit in the surrounding `if`/`while` blocks). No test. |  |
| [#unexportnonembeddableir](../../../design/target-pipelines/hlsl.md#unexportnonembeddableir) | undocumented-behavior | The doc's Phase C diagram mentions `unexportNonEmbeddableIR` as gated on `EmbedDownstreamIR`. The `-embed-downstream-ir` switch is a command-line surface; the doc does not anchor a text-emit marker. |  |
| [#source](../../../design/target-pipelines/hlsl.md#source) | undocumented-behavior | The doc's `## Source` table cites line numbers (`linkAndOptimizeIR` at line ~893, `emitEntryPointsSourceFromIR` at line ~2418, the `HLSLSourceEmitter` constructor at line ~2507). These are navigation aids and not user-observable; no test. |  |
| [#hlsl-has-no-iterative-passes-in-linkandoptimizeir](../../../design/target-pipelines/hlsl.md#hlsl-has-no-iterative-passes-in-linkandoptimizeir) | undocumented-behavior | The doc states "HLSL has no iterative passes in `linkAndOptimizeIR`" but the consequence ("no extra simplification loop in the pass log") is not observable through `slangc -target hlsl` text. No test. |  |
| [#phase-d-hlsl-emit-and-downstream-tools](../../../design/target-pipelines/hlsl.md#phase-d-hlsl-emit-and-downstream-tools) | undocumented-behavior | The doc's Phase D table mentions `HLSLSourceEmitter` walks the IR and writes HLSL text, but does not enumerate which texture variants survive (`Texture1D`, `Texture2DArray`, `TextureCubeArray`, `Texture2DMS<T,N>`, `RWTexture1D`, `RWTexture2D`, `RWTexture3D`, `SamplerComparisonState`) nor the canonical method spellings (`Sample`, `SampleLevel`, `SampleGrad`, `Load`, `GatherRed`/`GatherGreen`/`GatherBlue`/`GatherAlpha`, `SampleCmp`, `SampleCmpLevelZero`). | A one-line statement that each Slang texture/sampler variant emits as the same HLSL native type name with the matching `register(t\|u\|s)` class would let tests anchor more precisely than the general `#phase-d-hlsl-emit-and-downstream-tools` section. |
