---
generated: true
model: claude-fable-5
generated_at: 2026-07-08T16:30:00Z
source_commit: 110ca68915f1b6690e19a647e3437e1ad1f78a03
watched_paths_digest: ee8f5d22353edfd7c8285d12947d6ecb5b807ed2567feebd8c556abbff308de1
source_doc: docs/generated/design/pipeline/04-ast-to-ir.md
source_doc_digest: 0c811a87ac30a9bd7739f1990c1c695adcfbacd1611a578aa0d650aa80cf4d7e
warning: "Auto-generated. May drift from source. Do not edit by hand."
---

# Tests for pipeline/04-ast-to-ir

## Intent

Tests verify the AST → IR lowering claims described in
[`docs/generated/design/pipeline/04-ast-to-ir.md`](../../../design/pipeline/04-ast-to-ir.md):
that each documented AST node family lowers to the IR construct the
doc names (`FuncDecl` → `IRFunc`, `VarDecl` → `IRVar`/`IRGlobalVar`,
`StructDecl` → `IRStructType` with `IRStructField` children,
`InterfaceDecl` → `IRInterfaceType` whose requirement entries are
addressed by requirement keys (`IRStructKey`s, or hoistable
`IRBuiltinRequirementKey`s for recognized built-in requirements),
`GenericDecl` → `IRGeneric`, `BlockStmt` → basic blocks, structured
branches `IfStmt`/`ForStmt`/`WhileStmt`/`SwitchStmt` → `ifElse` /
`loop` / `switch` terminators with explicit join operand,
`ReturnStmt` → `return_val`, `BuiltinOperatorExpr` (the checker's
fast-path rewrite of recognized builtin operators) → single pure
value insts emitted without callable resolution (with `%` selecting
`frem` vs `irem` by element type, and `?:` / `&&` / `||` carved out
to their dedicated control-flow paths),
`InvokeExpr` → `call`, `MemberExpr` → `get_field` / `get_field_addr`
depending on rvalue/lvalue context, `LiteralExpr` → constant inst,
`WitnessTable` → `IRWitnessTable`), that phi-style joining is
encoded as block parameters rather than explicit `phi`, that
specialization is **deferred** to a later IR pass (a generic call
appears as `call specialize(%generic, <Type>)(...)`, not as an
inlined body), and that the lowering step excludes IR for `import`ed
modules (those flow through `[import("...")]` decorations and are
linked in later).

The primary observation mechanism is `-target spirv-asm -dump-ir -o
/dev/null` followed by a FileCheck against the IR dump, anchored on
the user-named function (`func %main` or a helper) to cut through the
preamble of capability sets, core-module imports, and
differentiation glue. All claims here are target-independent IR-shape
claims, so the bundle uses a single SPIR-V `-dump-ir` directive per
test rather than multi-target SIMPLE — the doc never asserts a
target-conditional lowering behavior.

Cross-cutting decoration / opcode catalog coverage (`entryPoint`,
`nameHint`, the per-opcode catalog shape) lives in
[`cross-cutting/ir-instructions`](../../cross-cutting/ir-instructions/);
this bundle anchors on the AST-side of the mapping ("which AST node
lowers to which IR construct").

## Functional coverage

| Claim                                                                                                                                                                                                                                                                                       | Intent     | Anchor                                                                                                                     | Tests                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| A builtin scalar `a + b` is emitted directly as one pure `add` inst by the checker fast path; no `call` instruction appears in the lowered body because callable resolution is skipped.                                                                                                     | functional | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`builtinop-scalar-add-fast-path-no-call.slang`](builtinop-scalar-add-fast-path-no-call.slang)                                               |
| A builtin `+` on `float3` vector operands takes the checker fast path and lowers to a single pure `add` inst whose result IR type is `Vec(Float, 3 : Int)` — no call instruction.                                                                                                           | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`builtinop-vector-add-single-pure-inst.slang`](builtinop-vector-add-single-pure-inst.slang)                                                 |
| A builtin elementwise `+` on `float2x2` matrix operands takes the checker fast path and lowers to a single pure `add` inst whose result IR type is the matrix type `Mat(Float, 2 : Int, 2 : Int, ...)`.                                                                                     | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`builtinop-matrix-add-single-pure-inst.slang`](builtinop-matrix-add-single-pure-inst.slang)                                                 |
| A builtin `==` on `bool` operands is fast-pathed like numeric operands and lowers to a single pure `cmpEQ` inst — no call instruction precedes it in the body.                                                                                                                              | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`builtinop-bool-operands-cmpeq-fast-path.slang`](builtinop-bool-operands-cmpeq-fast-path.slang)                                             |
| A builtin `a % b` on integer operands lowers to an `irem` IR opcode — the doc says `%` picks `IRIRem` for non-floating-point operands.                                                                                                                                                      | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`binaryexpr-mod-lowers-to-irem.slang`](binaryexpr-mod-lowers-to-irem.slang)                                                                 |
| A builtin `a % b` on `float` operands picks the floating-point remainder opcode `frem` — the element-type selection for `%` (IRFRem for floating-point operands).                                                                                                                           | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`binaryexpr-mod-float-lowers-to-frem.slang`](binaryexpr-mod-float-lowers-to-frem.slang)                                                     |
| A builtin `a % b` on `double` operands picks `frem` with result IR type `Double` — the floating-point side of the `%` element-type selection at double precision.                                                                                                                           | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`binaryexpr-mod-double-lowers-to-frem.slang`](binaryexpr-mod-double-lowers-to-frem.slang)                                                   |
| A short-circuit logical-OR of `(a > b)` and `(c < d)` is excluded from the builtin fast path and lowers through its dedicated control-flow path — an `ifElse(...)` whose join block receives the Bool via a block-parameter branch argument, with the RHS evaluated only on the false edge. | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`shortcircuit-or-encodes-as-ifelse-with-block-param.slang`](shortcircuit-or-encodes-as-ifelse-with-block-param.slang)                       |
| A scalar `cond ? x : y` is excluded from the builtin fast path and lowers through its dedicated control-flow path: an `ifElse(...)` joining through a block parameter, not a single pure-value inst.                                                                                        | boundary   | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | [`ternary-conditional-lowers-via-control-flow.slang`](ternary-conditional-lowers-via-control-flow.slang)                                     |
| A GenericDecl lowers to an `IRGeneric` (function-shaped IR inst whose body computes a type-level value); specialization is NOT performed at lowering.                                                                                                                                       | functional | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`genericdecl-lowers-to-irgeneric.slang`](genericdecl-lowers-to-irgeneric.slang)                                                             |
| A WitnessTable synthesized in checking lowers to an `IRWitnessTable` whose entries map interface requirements to concrete implementations.                                                                                                                                                  | functional | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`witness-table-lowers-to-ir-witness-table.slang`](witness-table-lowers-to-ir-witness-table.slang)                                           |
| A five-deep chain of generic-from-generic calls lowers to five `IRGeneric` wrappers; each generic body holds an unspecialized `call specialize(...)` to the inner generic — confirming that specialization is deferred recursively.                                                         | stress     | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`generic-recursive-depth-five-call-chain-specialize.slang`](generic-recursive-depth-five-call-chain-specialize.slang)                       |
| A generic function declaring two distinct type parameters lowers without specialization; the call site emits `call specialize(%g, Int, Float)(...)` carrying both type arguments in source order.                                                                                           | boundary   | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`generic-multi-typearg-call-specialize-two-types.slang`](generic-multi-typearg-call-specialize-two-types.slang)                             |
| A generic with one type parameter but four value arguments lowers to a `call specialize(%g, Int)(%a, %a, %a, %a)` — value arguments flow through the inner call operand list, the type list stays at length one.                                                                            | boundary   | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`generic-multi-value-args-call-specialize-four-values.slang`](generic-multi-value-args-call-specialize-four-values.slang)                   |
| A single generic function called with three distinct type arguments lowers to a single `IRGeneric` and three independent `call specialize(%g, T_k)` sites — each specialization is deferred and emitted at the use site, not at the definition.                                             | stress     | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`generic-call-three-distinct-specializations-each-deferred.slang`](generic-call-three-distinct-specializations-each-deferred.slang)         |
| A two-method interface conformance lowers to an `IRWitnessTable` carrying two `witness_table_entry(req, impl)` rows — one per interface requirement.                                                                                                                                        | boundary   | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`witness-table-two-methods-two-entries.slang`](witness-table-two-methods-two-entries.slang)                                                 |
| Lowering does not specialize generics; a generic call appears as `call specialize(%generic, <Type>)(...)`, not as an inlined body.                                                                                                                                                          | functional | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`specialization-deferred-to-ir-pass.slang`](specialization-deferred-to-ir-pass.slang)                                                       |
| Each ordinary interface method requirement gets its own per-decl `IRStructKey` (`= key` in the dump) carrying a `key_`-prefixed mangled linkage name that unifies the key across modules.                                                                                                   | functional | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`interface-ordinary-requirement-key-per-decl.slang`](interface-ordinary-requirement-key-per-decl.slang)                                     |
| Two structs conforming to IDifferentiable share one hoistable `builtinRequirementKey` inst per built-in requirement — both witness tables carry an entry keyed by the same key inst.                                                                                                        | boundary   | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`builtin-requirement-key-dedup-across-two-structs.slang`](builtin-requirement-key-dedup-across-two-structs.slang)                           |
| An interface-level subtype constraint (`interface IDerived : IBase`) lowers as its own requirement entry whose requirement value is a WitnessTableType — `interface_req_entry(%key, witness_table_t(%IBase))`.                                                                              | functional | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`interface-inheritance-constraint-req-entry-witness-table-type.slang`](interface-inheritance-constraint-req-entry-witness-table-type.slang) |
| A subtype bound on an associated type (`associatedtype Elem : IBase`) is relocated to interface level and lowers to a requirement entry whose requirement value is `witness_table_t(%IBase)`.                                                                                               | boundary   | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | [`interface-assoctype-bound-constraint-witness-table-type.slang`](interface-assoctype-bound-constraint-witness-table-type.slang)             |
| References to symbols defined in an imported module (e.g. the core module) appear in the lowered IR with `[import("...")]` decorations rather than as full function bodies; the doc says "The lowering step does NOT include the IR for imported modules".                                  | functional | [#inputs-and-outputs](../../../design/pipeline/04-ast-to-ir.md#inputs-and-outputs)                                         | [`import-not-lowered-into-translation-unit.slang`](import-not-lowered-into-translation-unit.slang)                                           |
| A builtin `a != b` (a checker fast-path BuiltinOperatorExpr) lowers to `cmpNE` — sibling of cmpEQ in the doc's BuiltinOperatorExpr row.                                                                                                                                                     | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-ne-lowers-to-cmpne.slang`](binaryexpr-ne-lowers-to-cmpne.slang)                                                                 |
| A builtin `a & b` (bitwise AND, a checker fast-path BuiltinOperatorExpr) lowers to an `and` IR opcode — the doc's BuiltinOperatorExpr row explicitly names bitwise operators (`IRBitAnd`).                                                                                                  | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-bitand-lowers-to-and.slang`](binaryexpr-bitand-lowers-to-and.slang)                                                             |
| A builtin `a * b` (a checker fast-path BuiltinOperatorExpr) lowers to a `mul` IR opcode, matching the doc's `IRMul` exemplar of the BuiltinOperatorExpr row.                                                                                                                                | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-mul-lowers-to-mul.slang`](binaryexpr-mul-lowers-to-mul.slang)                                                                   |
| A builtin `a - b` (a checker fast-path BuiltinOperatorExpr) lowers to a `sub` IR opcode in the doc's "BuiltinOperatorExpr -> a single pure value inst" row; the IRSub mirror of IRAdd.                                                                                                      | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-sub-lowers-to-sub.slang`](binaryexpr-sub-lowers-to-sub.slang)                                                                   |
| A builtin `a / b` (a checker fast-path BuiltinOperatorExpr) lowers to a `div` IR opcode in the doc's single-pure-value-inst row.                                                                                                                                                            | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-div-lowers-to-div.slang`](binaryexpr-div-lowers-to-div.slang)                                                                   |
| A builtin `a < b` (a checker fast-path BuiltinOperatorExpr) lowers to `cmpLT` — sibling of cmpEQ/cmpGT in the doc's BuiltinOperatorExpr row.                                                                                                                                                | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-lt-lowers-to-cmplt.slang`](binaryexpr-lt-lowers-to-cmplt.slang)                                                                 |
| A builtin `a << n` (a checker fast-path BuiltinOperatorExpr) lowers to an `shl` IR opcode — a pure-value inst representing left-shift in the doc's BuiltinOperatorExpr row.                                                                                                                 | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-shl-lowers-to-shl.slang`](binaryexpr-shl-lowers-to-shl.slang)                                                                   |
| A builtin `a == b` (a checker fast-path BuiltinOperatorExpr) lowers to `cmpEQ` — the doc's `IREq` exemplar of the BuiltinOperatorExpr row.                                                                                                                                                  | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-eq-lowers-to-cmpeq.slang`](binaryexpr-eq-lowers-to-cmpeq.slang)                                                                 |
| A builtin arithmetic site (`a + b`, a checker fast-path BuiltinOperatorExpr) lowers to a single pure-value IR opcode (`add`) — the doc's "single pure value inst (IRAdd, IRMul, ...)" row.                                                                                                  | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-arithmetic-lowers-to-add.slang`](binaryexpr-arithmetic-lowers-to-add.slang)                                                     |
| A builtin comparison site (`a > 0`, a checker fast-path BuiltinOperatorExpr) lowers to a comparison IR opcode (`cmpGT`) — the doc's BuiltinOperatorExpr row.                                                                                                                                | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`binaryexpr-comparison-lowers-to-cmpgt.slang`](binaryexpr-comparison-lowers-to-cmpgt.slang)                                                 |
| A BlockStmt containing a single statement (no control flow) lowers to a single entry IRBlock; lowering does not introduce extra blocks just because of the brace nesting.                                                                                                                   | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`blockstmt-single-stmt-block-collapses.slang`](blockstmt-single-stmt-block-collapses.slang)                                                 |
| A BlockStmt lowers to a sequence of basic blocks; the function body has multiple `block %{{.*}}` regions when control flow branches.                                                                                                                                                        | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`blockstmt-lowers-to-basic-blocks.slang`](blockstmt-lowers-to-basic-blocks.slang)                                                           |
| A ForStmt lowers to a `loop` terminator; the induction variable is carried as a block `param` (phi-style joining encoded as block parameters).                                                                                                                                              | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`forstmt-lowers-to-loop-with-block-params.slang`](forstmt-lowers-to-loop-with-block-params.slang)                                           |
| A FuncDecl lowers to an IRFunc whose body contains one or more IRBlocks; a callsite lowers to a `call` instruction.                                                                                                                                                                         | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-lowers-to-irfunc.slang`](funcdecl-lowers-to-irfunc.slang)                                                                         |
| A FuncDecl that calls itself lowers to a single IRFunc whose body contains a `call %self(...)` instruction targeting the same IRFunc — the doc's `InvokeExpr -> IRCall` row applied to a self-reference.                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-recursive-call-self-references-irfunc.slang`](funcdecl-recursive-call-self-references-irfunc.slang)                               |
| A FuncDecl that returns a multi-field struct lowers to an IRFunc whose function type names the struct as its return type; the body builds the struct in an IRVar and returns its loaded value.                                                                                              | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-returns-struct-lowers-to-return-val-struct.slang`](funcdecl-returns-struct-lowers-to-return-val-struct.slang)                     |
| A FuncDecl with a default-valued parameter lowers normally; the omitted argument at the call site is materialized as a literal operand in the `call` instruction.                                                                                                                           | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-default-arg-materialized-at-call-site.slang`](funcdecl-default-arg-materialized-at-call-site.slang)                               |
| A FuncDecl with an `out int y` parameter lowers to an IRFunc whose param has type `OutParam(Int)`; writes through `y` lower to `store(%y, ...)` and the call site passes the address of a local IRVar.                                                                                      | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-out-param-lowers-to-outparam-pointer.slang`](funcdecl-out-param-lowers-to-outparam-pointer.slang)                                 |
| A FuncDecl with eight parameters lowers to an IRFunc whose entry block carries eight `param` instructions in declaration order.                                                                                                                                                             | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-many-params-eight-block-params.slang`](funcdecl-many-params-eight-block-params.slang)                                             |
| A FuncDecl with zero parameters lowers to an IRFunc whose entry block has no `param` instructions; the function type carries only the return type.                                                                                                                                          | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-zero-params-no-block-params.slang`](funcdecl-zero-params-no-block-params.slang)                                                   |
| A LiteralExpr lowers to a constant IR instruction (IRIntLit / IRFloatLit) visible as the literal value inline.                                                                                                                                                                              | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`literalexpr-lowers-to-constant.slang`](literalexpr-lowers-to-constant.slang)                                                               |
| A MemberExpr in rvalue position lowers to `IRFieldExtract` (spelled `get_field` in the dump).                                                                                                                                                                                               | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`memberexpr-rvalue-lowers-to-get-field.slang`](memberexpr-rvalue-lowers-to-get-field.slang)                                                 |
| A MemberExpr used as an assignment target (lvalue) lowers to `IRFieldAddress` (spelled `get_field_addr` in the dump).                                                                                                                                                                       | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`memberexpr-lvalue-lowers-to-get-field-addr.slang`](memberexpr-lvalue-lowers-to-get-field-addr.slang)                                       |
| A ReturnStmt lowers to an `IRReturn` terminator (spelled `return_val(...)` in the IR dump).                                                                                                                                                                                                 | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`returnstmt-lowers-to-return-val.slang`](returnstmt-lowers-to-return-val.slang)                                                             |
| A ReturnStmt nested inside a ForStmt lowers to a `return_val(...)` terminator in a block reached from the loop body, alongside the `loop(...)` structured-branch terminator — the doc's "ReturnStmt -> IRReturn" claim is unaffected by enclosing control flow.                             | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`return-from-inside-loop-emits-return-val-in-loop-block.slang`](return-from-inside-loop-emits-return-val-in-loop-block.slang)               |
| A StructDecl containing another StructDecl as a field lowers to an outer IRStructType whose `field(...)` row names the inner IRStructType; a nested member assignment lowers to chained `get_field_addr` instructions.                                                                      | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`structdecl-nested-struct-field-lowers-to-field-of-struct-type.slang`](structdecl-nested-struct-field-lowers-to-field-of-struct-type.slang) |
| A StructDecl lowers to an `IRStructType` parent instruction containing `IRStructField` children.                                                                                                                                                                                            | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`structdecl-lowers-to-struct-with-fields.slang`](structdecl-lowers-to-struct-with-fields.slang)                                             |
| A StructDecl whose field is `int16_t` lowers with that field's IR type as `Int16` inside the `field(...)` row.                                                                                                                                                                              | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int16-struct-field.slang`](lower-int16-struct-field.slang)                                                                           |
| A StructDecl whose field is `uint8_t` lowers with the field IR type `UInt8`.                                                                                                                                                                                                                | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint8-struct-field.slang`](lower-uint8-struct-field.slang)                                                                           |
| A StructDecl with eight scalar fields lowers to an IRStructType carrying eight `field(...)` children in source order.                                                                                                                                                                       | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`structdecl-many-fields-eight-fields.slang`](structdecl-many-fields-eight-fields.slang)                                                     |
| A StructDecl with exactly one scalar field lowers to an IRStructType carrying exactly one `field(...)` child — sibling of the empty (zero-field is not tested) and the eight-field boundary cases.                                                                                          | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`structdecl-single-field-lowers-to-one-field.slang`](structdecl-single-field-lowers-to-one-field.slang)                                     |
| A SwitchStmt lowers to a `switch` structured-branch terminator with case-value/case-block operand pairs.                                                                                                                                                                                    | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`switchstmt-lowers-to-switch.slang`](switchstmt-lowers-to-switch.slang)                                                                     |
| A SwitchStmt with a default and a single explicit case lowers to a `switch(scrutinee, merge, default, k, block)` — minimum non-trivial case count.                                                                                                                                          | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`switchstmt-default-only-single-default-arm.slang`](switchstmt-default-only-single-default-arm.slang)                                       |
| A SwitchStmt with five explicit cases lowers to a single `switch(...)` terminator carrying five case-value / case-block operand pairs in source order.                                                                                                                                      | stress     | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`switchstmt-five-cases-five-pairs.slang`](switchstmt-five-cases-five-pairs.slang)                                                           |
| A WhileStmt lowers to a `loop` structured-branch terminator (sibling of for; doc lists `WhileStmt` in the same row as `ForStmt`).                                                                                                                                                           | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`whilestmt-lowers-to-loop.slang`](whilestmt-lowers-to-loop.slang)                                                                           |
| A `BuiltinOperatorExpr` on `double` operands lowers to `mul` whose result IR type is `Double`.                                                                                                                                                                                              | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-double-arithmetic.slang`](lower-double-arithmetic.slang)                                                                             |
| A `BuiltinOperatorExpr` on `half` operands lowers to `add` whose result IR type is `Half`.                                                                                                                                                                                                  | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-half-arithmetic.slang`](lower-half-arithmetic.slang)                                                                                 |
| A `BuiltinOperatorExpr` on `int16_t` operands lowers to `add` whose result type carries through the narrow `Int16` IR type.                                                                                                                                                                 | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int8-arithmetic.slang`](lower-int8-arithmetic.slang)                                                                                 |
| A `BuiltinOperatorExpr` on `uint64_t` operands lowers to `add` whose result IR type is `UInt64`.                                                                                                                                                                                            | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint64-arithmetic.slang`](lower-uint64-arithmetic.slang)                                                                             |
| A `ParameterBlock<Narrow>` over a struct of narrow types lowers to a `global_param` whose IR type is `ParameterBlock(%Narrow)`; the inner struct's `field(...)` rows preserve each narrow type.                                                                                             | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-parameter-block-narrow-struct.slang`](lower-parameter-block-narrow-struct.slang)                                                     |
| A `RWStructuredBuffer<Narrow>` over a struct with narrow integer fields lowers so the per-element `Ptr(%Narrow)` is returned by `rwstructuredBufferGetElementPtr`, and the struct's narrow-typed `field(...)` rows survive.                                                                 | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-buffer-of-struct-with-narrow-types.slang`](lower-buffer-of-struct-with-narrow-types.slang)                                           |
| A `RWStructuredBuffer<int64_t>` lowers so the element pointer returned by `rwstructuredBufferGetElementPtr` is `Ptr(Int64)`.                                                                                                                                                                | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int64-buffer-element.slang`](lower-int64-buffer-element.slang)                                                                       |
| A `Tuple<half, uint16_t>` lowers to `tuple_type(Half, UInt16)` — narrow-precision pair carries through tuple IR type.                                                                                                                                                                       | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-tuple-narrow-pair.slang`](lower-tuple-narrow-pair.slang)                                                                             |
| A `Tuple<int8_t, float, bool>` constructor lowers to a `makeTuple(...)` whose result IR type is `tuple_type(Int8, Float, Bool)` carrying each element's lowered IR type.                                                                                                                    | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-tuple-heterogeneous.slang`](lower-tuple-heterogeneous.slang)                                                                         |
| A `matrix<double, 2, 4>` rectangular matrix lowers with IR type `Mat(Double, 2 : Int, 4 : Int, 0 : Int)`.                                                                                                                                                                                   | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-mat-double-rectangular.slang`](lower-mat-double-rectangular.slang)                                                                   |
| A `matrix<double, 4, 4>` global lowers with IR type `Mat(Double, 4 : Int, 4 : Int, 0 : Int)`.                                                                                                                                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-double-matrix.slang`](lower-double-matrix.slang)                                                                                     |
| A `matrix<half, 3, 2>` rectangular matrix lowers with IR type `Mat(Half, 3 : Int, 2 : Int, 0 : Int)`.                                                                                                                                                                                       | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-mat-half-rectangular.slang`](lower-mat-half-rectangular.slang)                                                                       |
| A `matrix<half, 3, 3>` global lowers with IR type `Mat(Half, 3 : Int, 3 : Int, 0 : Int)`.                                                                                                                                                                                                   | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-half-matrix.slang`](lower-half-matrix.slang)                                                                                         |
| A `return` from a void-returning function lowers to `return_val(void_constant)` — the doc's "ReturnStmt → IRReturn terminator" claim, void variant.                                                                                                                                         | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`return-void-uses-void-constant.slang`](return-void-uses-void-constant.slang)                                                               |
| A `uniform double` lowers with IR type `Double`.                                                                                                                                                                                                                                            | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-double-scalar.slang`](lower-double-scalar.slang)                                                                                     |
| A `uniform half` lowers with IR type `Half`.                                                                                                                                                                                                                                                | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-half-scalar.slang`](lower-half-scalar.slang)                                                                                         |
| A `vector<double, 3>` global lowers with IR type `Vec(Double, 3 : Int)`.                                                                                                                                                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-double3-vector.slang`](lower-double3-vector.slang)                                                                                   |
| A `vector<half, 3>` global lowers with IR type `Vec(Half, 3 : Int)`.                                                                                                                                                                                                                        | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-half3-vector.slang`](lower-half3-vector.slang)                                                                                       |
| A `vector<int64_t, 3>` global lowers with IR type `Vec(Int64, 3 : Int)`.                                                                                                                                                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int64-vector.slang`](lower-int64-vector.slang)                                                                                       |
| A `vector<int8_t, 4>` global lowers with IR type `Vec(Int8, 4 : Int)` — narrow-int element inside the vector storage form.                                                                                                                                                                  | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int8-vector.slang`](lower-int8-vector.slang)                                                                                         |
| A `vector<uint16_t, 2>` global lowers with IR type `Vec(UInt16, 2 : Int)`.                                                                                                                                                                                                                  | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint16-vector.slang`](lower-uint16-vector.slang)                                                                                     |
| A fixed-size array of `double` global lowers with IR type `Array(Double, N : Int)`.                                                                                                                                                                                                         | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-double-array.slang`](lower-double-array.slang)                                                                                       |
| A fixed-size array of `half` global lowers with IR type `Array(Half, N : Int)`.                                                                                                                                                                                                             | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-half-array.slang`](lower-half-array.slang)                                                                                           |
| A fixed-size array of `int8_t` global lowers with IR type `Array(Int8, N : Int)`.                                                                                                                                                                                                           | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int8-array.slang`](lower-int8-array.slang)                                                                                           |
| A fixed-size array of `uint64_t` global lowers with IR type `Array(UInt64, N : Int)`.                                                                                                                                                                                                       | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint64-array.slang`](lower-uint64-array.slang)                                                                                       |
| A float LiteralExpr lowers to an IRFloatLit constant inst spelled as `<value> : Float` inline in its operand position — the float-side of the doc's "LiteralExpr -> constant inst (IRIntLit, IRFloatLit, ...)" row.                                                                         | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`literalexpr-float-literal-lowers-to-float-constant.slang`](literalexpr-float-literal-lowers-to-float-constant.slang)                       |
| A function with five-deep nested IfStmts lowers each level to its own `ifElse(...)` terminator; the body grows into many basic blocks (then / else / merge per level).                                                                                                                      | stress     | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`blockstmt-nested-five-deep-multiple-blocks.slang`](blockstmt-nested-five-deep-multiple-blocks.slang)                                       |
| A global fixed-size array of struct elements lowers with IR type `Array(%Struct, N : Int)`; subscripting the array uses `getElement` to recover the struct element value.                                                                                                                   | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-array-of-structs.slang`](lower-array-of-structs.slang)                                                                               |
| A local VarDecl whose address is taken (struct field access) lowers to an `IRVar` allocated inside the enclosing block.                                                                                                                                                                     | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`vardecl-local-struct-lowers-to-irvar.slang`](vardecl-local-struct-lowers-to-irvar.slang)                                                   |
| A method-call InvokeExpr `s.act(v)` on a struct lowers to a `call %S_act(...)` (the same `IRCall` family the doc lists) with the struct-typed receiver passed as the first argument.                                                                                                        | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`invokeexpr-method-call-on-struct-lowers-to-call.slang`](invokeexpr-method-call-on-struct-lowers-to-call.slang)                             |
| A module-scope `static const int N = 42;` lowers to a `globalConstant(42 : Int)` IR value bound to a named global; reads of `N` in `main` reference the named global, not the inline literal.                                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`static-const-lowers-to-global-constant.slang`](static-const-lowers-to-global-constant.slang)                                               |
| A module-scope `uniform int16_t` lowers with IR type `Int16`.                                                                                                                                                                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int16-scalar.slang`](lower-int16-scalar.slang)                                                                                       |
| A module-scope `uniform int64_t` lowers with IR type `Int64`.                                                                                                                                                                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int64-scalar.slang`](lower-int64-scalar.slang)                                                                                       |
| A module-scope `uniform int8_t` lowers with IR type `Int8`; the doc's "VarDecl(global) -> IRGlobalVar" row at the narrow-integer end of the type axis.                                                                                                                                      | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-int8-scalar.slang`](lower-int8-scalar.slang)                                                                                         |
| A module-scope `uniform uint16_t` lowers with IR type `UInt16`.                                                                                                                                                                                                                             | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint16-scalar.slang`](lower-uint16-scalar.slang)                                                                                     |
| A module-scope `uniform uint64_t` lowers with IR type `UInt64`.                                                                                                                                                                                                                             | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint64-scalar.slang`](lower-uint64-scalar.slang)                                                                                     |
| A module-scope `uniform uint8_t` lowers with IR type `UInt8`; the doc's "VarDecl(global) -> IRGlobalVar" row at the unsigned narrow-integer end of the type axis.                                                                                                                           | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-uint8-scalar.slang`](lower-uint8-scalar.slang)                                                                                       |
| A module-scope uniform VarDecl lowers to an `IRGlobalVar` (spelled `global_param` in the IR dump).                                                                                                                                                                                          | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`vardecl-global-uniform-lowers-to-global-param.slang`](vardecl-global-uniform-lowers-to-global-param.slang)                                 |
| A non-square `float2x4` matrix lowers with IR type `Mat(Float, 2 : Int, 4 : Int, 0 : Int)`; the row/column operands appear in source order.                                                                                                                                                 | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-mat2x4-rectangular.slang`](lower-mat2x4-rectangular.slang)                                                                           |
| A non-square `float4x2` matrix lowers with IR type `Mat(Float, 4 : Int, 2 : Int, 0 : Int)` — the row/column dimensions are not confused with `float2x4`.                                                                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-mat4x2-rectangular.slang`](lower-mat4x2-rectangular.slang)                                                                           |
| A short-circuit `(a > b) && (c < d)` lowers to an `ifElse(...)` terminator whose true/false blocks unconditionally branch to a merge block carrying the joined Bool as a block parameter — the doc's phi-as-block-param encoding applied to short-circuit logic.                            | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`shortcircuit-and-encodes-as-ifelse-with-block-param.slang`](shortcircuit-and-encodes-as-ifelse-with-block-param.slang)                     |
| A struct mixing narrow integer, half, float, double, and uint16 fields lowers so each `field(...)` row carries its element's lowered IR type verbatim.                                                                                                                                      | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-struct-of-mixed-precision.slang`](lower-struct-of-mixed-precision.slang)                                                             |
| A struct whose field is `double` lowers with that field's IR type as `Double` inside the `field(...)` row.                                                                                                                                                                                  | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-double-struct-field.slang`](lower-double-struct-field.slang)                                                                         |
| A struct whose field is `half` lowers with that field's IR type as `Half` inside the `field(...)` row.                                                                                                                                                                                      | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-half-struct-field.slang`](lower-half-struct-field.slang)                                                                             |
| A struct whose fields are fixed-size arrays lowers so each `field(...)` row carries an `Array(...)` IR type — composition of StructDecl + Array rows.                                                                                                                                       | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-struct-of-arrays.slang`](lower-struct-of-arrays.slang)                                                                               |
| A subscript-assignment on an `RWStructuredBuffer<T>` lowers to `rwstructuredBufferGetElementPtr` followed by `store`.                                                                                                                                                                       | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`rwbuffer-write-lowers-to-getelementptr-store.slang`](rwbuffer-write-lowers-to-getelementptr-store.slang)                                   |
| A unary `~a` (bitwise NOT) lowers to a `bitnot` IR opcode — a pure-value inst in the doc's BuiltinOperatorExpr row (bitwise / unary fast path).                                                                                                                                             | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`unaryexpr-bitnot-lowers-to-bitnot.slang`](unaryexpr-bitnot-lowers-to-bitnot.slang)                                                         |
| A unary minus `-a` lowers to a `neg` IR opcode; the doc's BuiltinOperatorExpr fast-path row explicitly covers unary operators (`IRNeg`).                                                                                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`unaryexpr-neg-lowers-to-neg.slang`](unaryexpr-neg-lowers-to-neg.slang)                                                                     |
| A uniform `uint` plus the literal `1u` lowers to a runtime `add(%a, 1 : UInt)` instruction; lowering does not pre-compute the sum because one operand is non-constant.                                                                                                                      | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`literalexpr-uint-max-runtime-add-one-not-folded.slang`](literalexpr-uint-max-runtime-add-one-not-folded.slang)                             |
| A void-returning FuncDecl with an empty body lowers to an IRFunc whose sole block is a single `return_val(void_constant)` terminator.                                                                                                                                                       | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`funcdecl-empty-body-lowers-to-return-val-void.slang`](funcdecl-empty-body-lowers-to-return-val-void.slang)                                 |
| An IfStmt lowers to an `ifElse` structured-branch terminator whose merge / join point is an explicit operand.                                                                                                                                                                               | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`ifstmt-lowers-to-ifelse.slang`](ifstmt-lowers-to-ifelse.slang)                                                                             |
| An IfStmt with no `else` clause still lowers to an `ifElse(...)` terminator carrying an explicit merge operand; the missing else-branch is represented by an empty/false-block jumping directly to the merge.                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`ifstmt-no-else-lowers-to-ifelse-merge.slang`](ifstmt-no-else-lowers-to-ifelse-merge.slang)                                                 |
| An InterfaceDecl lowers to an `IRInterfaceType` whose per-method `interface_req_entry` rows are keyed by requirement-key insts.                                                                                                                                                             | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`interfacedecl-lowers-to-interface-with-req-entries.slang`](interfacedecl-lowers-to-interface-with-req-entries.slang)                       |
| An InterfaceDecl with exactly one method lowers to one `interface_req_entry(...)` row plus an `interface(...)` declaration with that single requirement.                                                                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`interfacedecl-single-method-one-req-entry.slang`](interfacedecl-single-method-one-req-entry.slang)                                         |
| An InterfaceDecl with five methods lowers to five `interface_req_entry(...)` rows referenced by a single `interface(%1, %2, %3, %4, %5)` declaration, scaling the doc's InterfaceDecl requirement-entry claim.                                                                              | stress     | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`interfacedecl-five-methods-five-req-entries.slang`](interfacedecl-five-methods-five-req-entries.slang)                                     |
| An InterfaceDecl with three methods lowers to one `interface_req_entry(...)` instruction per method; the interface type aggregates them into a single `interface(...)` operand list.                                                                                                        | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`interfacedecl-three-methods-three-req-entries.slang`](interfacedecl-three-methods-three-req-entries.slang)                                 |
| An InterfaceDecl with zero methods lowers to an `IRInterfaceType` carrying no method requirement entries — the witness table for a conforming type still exists but is empty.                                                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`interfacedecl-empty-no-req-entry.slang`](interfacedecl-empty-no-req-entry.slang)                                                           |
| An InvokeExpr (general operator / function call) lowers, after callable resolution, to an `IRCall` (spelled `call %<callee>(...)` in the dump).                                                                                                                                             | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`invokeexpr-lowers-to-call.slang`](invokeexpr-lowers-to-call.slang)                                                                         |
| An assignment to a struct field lowers to a `store(%addr, %value)`; reading the field back lowers to a `load(%addr)`.                                                                                                                                                                       | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`load-store-from-local-pointer.slang`](load-store-from-local-pointer.slang)                                                                 |
| An explicit `float(doubleValue)` cast lowers to `floatCast(%double)` — double-to-float narrowing in the float-to-float family.                                                                                                                                                              | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-cast-double-to-float.slang`](lower-cast-double-to-float.slang)                                                                       |
| An explicit `float(halfValue)` constructor-style cast lowers to `floatCast(%half)` — float-to-float family.                                                                                                                                                                                 | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-cast-half-to-float.slang`](lower-cast-half-to-float.slang)                                                                           |
| An explicit `int(int64Value)` cast lowers to `intCast(%int64)` — wide-to-narrow signed integer conversion in the int-to-int family.                                                                                                                                                         | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-cast-int64-to-int.slang`](lower-cast-int64-to-int.slang)                                                                             |
| An explicit `int(int8Value)` cast lowers to `intCast(%int8)` — narrow-to-wide signed integer conversion in the int-to-int family.                                                                                                                                                           | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-cast-int8-to-int.slang`](lower-cast-int8-to-int.slang)                                                                               |
| An explicit constructor-style cast `int(x)` between primitive numeric types lowers to a dedicated conversion IR opcode (`castFloatToInt` / `castIntToFloat`), produced from a `TypeCastExpr` AST node.                                                                                      | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`conversion-explicit-cast-lowers-to-castfloattoint.slang`](conversion-explicit-cast-lowers-to-castfloattoint.slang)                         |
| An explicit constructor-style cast between two integer widths/signednesses (`uint(intValue)`) lowers to an `intCast` IR opcode — the integer-to-integer counterpart of `castFloatToInt`.                                                                                                    | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`cast-uint-from-int-lowers-to-intcast.slang`](cast-uint-from-int-lowers-to-intcast.slang)                                                   |
| Multiple ReturnStmts in a single FuncDecl each lower to their own `return_val(...)` terminator inside distinct basic blocks, all of which terminate the same IRFunc.                                                                                                                        | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`returnstmt-early-return-emits-multiple-return-val.slang`](returnstmt-early-return-emits-multiple-return-val.slang)                         |
| Multiple module-scope `uniform VarDecl`s each lower to a `global_param` IR value, preserving source order and each carrying its declared type.                                                                                                                                              | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`vardecl-multiple-global-uniforms-each-lowers-to-global-param.slang`](vardecl-multiple-global-uniforms-each-lowers-to-global-param.slang)   |
| Phi-style joining is encoded as block parameters (IRParam at the start of a block); branches to a block carry the parameter values as arguments — not via an explicit `phi` opcode.                                                                                                         | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`block-param-replaces-phi.slang`](block-param-replaces-phi.slang)                                                                           |
| Structured branches (`ifElse`) encode the join (merge) point as an explicit operand on the terminator; the two branches reach it via `unconditionalBranch`.                                                                                                                                 | functional | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`ifelse-merge-block-is-explicit-operand.slang`](ifelse-merge-block-is-explicit-operand.slang)                                               |
| Two nested ForStmts lower to two distinct `loop(...)` terminators inside `func %main`, each with its own induction-variable block parameter — sibling stress to the deep-if test.                                                                                                           | stress     | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`loop-nested-two-deep-emits-two-loop-instructions.slang`](loop-nested-two-deep-emits-two-loop-instructions.slang)                           |
| When both operands of `+` are compile-time integer literals (uint MAX and `1u`), the IRBuilder constant-folds at lowering and the body emits `store(..., 0 : UInt)` directly — no `add` instruction survives.                                                                               | boundary   | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`literalexpr-uint-max-literal-add-one-constant-folds.slang`](literalexpr-uint-max-literal-add-one-constant-folds.slang)                     |
| `Optional<int>` composes through lowering as `Optional(Int)`; the nested-type axis on a scalar inner type.                                                                                                                                                                                  | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-optional-int.slang`](lower-optional-int.slang)                                                                                       |
| `Optional<vector<half, 3>>` composes through lowering as `Optional(Vec(Half, 3 : Int))` — generic specialization of `Optional` over a narrow-precision vector element is deferred, but the storage IR type is observable.                                                                   | expansion  | [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                     | [`lower-optional-half3.slang`](lower-optional-half3.slang)                                                                                   |
| A FuncDecl registered as an entry point ends up in the lowered module with an `entryPoint(...)` decoration on its IRFunc.                                                                                                                                                                   | functional | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`entry-point-funcdecl-carries-entry-point-decoration.slang`](entry-point-funcdecl-carries-entry-point-decoration.slang)                     |
| A cbuffer containing a single scalar lowers to a `ConstantBuffer<...>` global parameter whose payload struct carries exactly one `field(...)` row.                                                                                                                                          | boundary   | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`cbuffer-single-scalar-lowers-to-one-field-struct.slang`](cbuffer-single-scalar-lowers-to-one-field-struct.slang)                           |
| A cbuffer mixing scalar, vector, and matrix fields lowers to a `ConstantBuffer<...>` payload struct whose `field(...)` rows carry each member's IR type verbatim (Int, Vec, Mat).                                                                                                           | boundary   | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`cbuffer-mixed-types-lowers-to-struct-with-mixed-fields.slang`](cbuffer-mixed-types-lowers-to-struct-with-mixed-fields.slang)               |
| An empty `cbuffer CB {}` lowers to a `ConstantBuffer(%SLANG_ParameterGroup_CB, ...)` global parameter and a body-less struct type; layout-intent annotation appears later in the pipeline.                                                                                                  | boundary   | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`cbuffer-empty-lowers-to-empty-struct.slang`](cbuffer-empty-lowers-to-empty-struct.slang)                                                   |
| Only FuncDecls registered as entry points carry an `entryPoint(...)` decoration; a sibling non-entry helper function in the same translation unit is lowered without that decoration.                                                                                                       | boundary   | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`non-entry-funcdecl-lacks-entry-point-decoration.slang`](non-entry-funcdecl-lacks-entry-point-decoration.slang)                             |
| Requesting an entry-point name that does not exist in the translation unit fires a "no function found matching entry point name 'main'" diagnostic before any IR module can be produced.                                                                                                    | negative   | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`entry-missing-name-fires-no-function-found.slang`](entry-missing-name-fires-no-function-found.slang)                                       |
| When two FuncDecls are registered as entry points in one translation unit, each lowered IRFunc carries its own `entryPoint(...)` decoration; the module-level entry-point list contains both.                                                                                               | boundary   | [#module-level-outputs](../../../design/pipeline/04-ast-to-ir.md#module-level-outputs)                                     | [`entry-point-multiple-each-gets-entry-point-decoration.slang`](entry-point-multiple-each-gets-entry-point-decoration.slang)                 |

## Untested claims

| Claim                                                                                                                                                                                                                                                                                                           | Reason               | Anchor                                                                                                                     | Why untested                                                                                                                                                                                                                                                     |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `generateIRForSpecializedComponentType` and `generateIRForTypeConformance` — component-type API entry points invoked through the `Session`, not through the command line. A C++ unit test would exercise them.                                                                                                  | (unclassified)       | [#generateirforspecializedcomponenttype](../../../design/pipeline/04-ast-to-ir.md#generateirforspecializedcomponenttype)   | Reason and explanation to be refined by the next regeneration.                                                                                                                                                                                                   |
| `IRBuilder` hash-consing decisions — the dump shows the post-dedup result, not the decision path.                                                                                                                                                                                                               | internal-source-fact | [#irbuilder-and-instruction-creation](../../../design/pipeline/04-ast-to-ir.md#irbuilder-and-instruction-creation)         | Which values were hash-consed (and when) is an internal `IRBuilder` decision; only the already-deduplicated result is observable through `-dump-ir`.                                                                                                             |
| `kIROpFlag_Hoistable` tags opcodes deduplicated by hash-consing; the separate `kIROpFlag_Global` marks opcodes always hoisted to module scope but **never** deduplicated.                                                                                                                                       | internal-source-fact | [#irbuilder-and-instruction-creation](../../../design/pipeline/04-ast-to-ir.md#irbuilder-and-instruction-creation)         | Flag bits on the opcode table; no dump surface distinguishes "hoisted because Global" from "hoisted-and-deduplicated because Hoistable".                                                                                                                         |
| Order of pass invocation inside `linkAndOptimizeIR` — belongs to `pipeline/05-ir-passes`.                                                                                                                                                                                                                       | (unclassified)       | [#linkandoptimizeir](../../../design/pipeline/04-ast-to-ir.md#linkandoptimizeir)                                           | Reason and explanation to be refined by the next regeneration.                                                                                                                                                                                                   |
| An assignment whose left-hand side the lowering switch cannot encode emits `Diagnostics::UnsupportedAssignmentTarget` (recovering the nearest non-zero source location) instead of aborting via `SLANG_UNIMPLEMENTED_X`; lowering errors flow through the front-end's `DiagnosticSink`.                         | (unclassified)       | [#diagnostics-during-lowering](../../../design/pipeline/04-ast-to-ir.md#diagnostics-during-lowering)                       | The doc names the diagnostic but neither a shader construct that reaches that switch arm nor the diagnostic's E-code; a DIAGNOSTIC_TEST must pin an explicit E#### code. Doc-gap row filed.                                                                      |
| Side artefacts on the surrounding `Module` (entry-point list, type-conformance bookkeeping, layout-intent markers) — these are C++ container contents, not observable through slangc CLI.                                                                                                                       | (unclassified)       | [#module](../../../design/pipeline/04-ast-to-ir.md#module)                                                                 | Reason and explanation to be refined by the next regeneration.                                                                                                                                                                                                   |
| The `slang-ir-insts-enum.h` FIDDLE-generated `IROp` enum — a build-time artefact.                                                                                                                                                                                                                               | compile-time-toggle  | [#irop](../../../design/pipeline/04-ast-to-ir.md#irop)                                                                     | Preprocessor define or build-time flag baked into the binary; not observable at runtime.                                                                                                                                                                         |
| Internal lowering visitor structure (which C++ visitor method handles which AST node) — implementation detail of `slang-lower-to-ir.cpp`, not surface-visible.                                                                                                                                                  | internal-source-fact | (unspecified)                                                                                                              | Implementation detail (C++ class hierarchy, field names, parser-callback names) with no user-observable consequence.                                                                                                                                             |
| A `BuiltinOperationIntVal` (the checked, folded form of a constant operator expression) lowers to the hoistable `constexpr*` opcode keyed on its `BuiltinOperationKind`, so equal compile-time expressions deduplicate to one inst.                                                                             | (unclassified)       | [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering) | The doc gives no example shader whose LOWER-TO-IR dump reliably surfaces a `constexpr*` op; the sibling `ir-reference/values` bundle records the same conclusion. Doc-gap row filed.                                                                             |
| A `countof(Pack) == Count` constraint on a variadic generic lowers as a proof-only witness: a hidden `IRParam` of `WitnessTableType(void)` on the enclosing `IRGeneric`, a single cached module-level `IRWitnessTable` for concrete instances, and an `IRGlobalGenericParam` for the global-generic-param form. | (unclassified)       | [#variadic-pack-count-witnesses](../../../design/pipeline/04-ast-to-ir.md#variadic-pack-count-witnesses)                   | The doc names checker/lowering internals (`GenericVariadicPackCountConstraintDecl`, the visitor functions) but no user-level Slang syntax that produces the constraint; without a doc-grounded surface any test expectation would be a guess. Doc-gap row filed. |
| The builtin requirement key carries an `IRBuiltinRequirementDecoration` so role-scanning consumers (autodiff) find a requirement by role, and the witness-table entry's `lookupKey` operand is typed `IRInst` rather than `IRStructKey`.                                                                        | internal-source-fact | [#generics-and-existentials](../../../design/pipeline/04-ast-to-ir.md#generics-and-existentials)                           | The C++ operand typing and the role-scanning consumer contract have no distinct slangc-observable surface beyond the key inst itself, which the dedup test already pins.                                                                                         |
| Lowering skips `maybeEmitDebugLine` / `maybeAddDebugLocationDecoration` for a Slang-synthesized initializer (`SynthesizedDefault` / `SynthesizedMemberInit` flavor) while a user-written `__init` keeps its debug info; the discrimination is by constructor flavor, not by the mangled `$init` name.           | out-of-bundle        | [#debug-info-gating](../../../design/pipeline/04-ast-to-ir.md#debug-info-gating)                                           | Pinned end-to-end by the hand-written regression test `tests/spirv/debug-info-synthesized-init.slang`; a LOWER-TO-IR probe would need the dump identifier of the synthesized `$init`, which the doc does not give.                                               |
| An existing per-target layout module is considered by `linkIR`, so its layout-decorated global symbols participate in linking even though it is not the executable per-translation-unit module.                                                                                                                 | out-of-bundle        | [#adjacent-pipelines](../../../design/pipeline/04-ast-to-ir.md#adjacent-pipelines)                                         | Link-stage behavior of the layout-only IR module; belongs to the `pipeline/04c-layout-ir` bundle, not the AST-to-IR lowering stage.                                                                                                                              |

## Doc gaps observed

| Anchor                                                                                                                                                                                                   | Kind                  | Gap                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Suggested addition                                                                                                                                                                    |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |   | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [#mapping-ast-constructs-to-ir](../../../design/pipeline/04-ast-to-ir.md#mapping-ast-constructs-to-ir)                                                                                                   | undocumented-behavior | The doc's "Mapping AST constructs to IR" table is explicitly "illustrative, not exhaustive" — a number of AST families that appear in practice are absent: `IndexExpr` (resource subscript / array element access), `AssignExpr` (the assignment itself, vs. the lvalue-side `get_field_addr` + `store`), `TypeCastExpr` (cast lowering — only mentioned implicitly through the arithmetic/comparison row), `BreakStmt` / `ContinueStmt` (loop exit / continue terminators). A single-line addition per row would let agents anchor tests for each. The bundle covers explicit casts and buffer indexing under the existing rows but with a stretched citation.                                                |                                                                                                                                                                                       |
| [#structured-branches-whose-join-point-is-an-explicit-operand-on-the-terminator](../../../design/pipeline/04-ast-to-ir.md#structured-branches-whose-join-point-is-an-explicit-operand-on-the-terminator) | undocumented-behavior | The doc says "structured branches whose join point is an explicit operand on the terminator" but does not say which operand position is the merge block for each terminator. The `cross-cutting/ir-instructions` doc has more detail on this; an explicit cross-reference would help.                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                       |
| [#the-lowering-visitor-descends-the-ast-top-down](../../../design/pipeline/04-ast-to-ir.md#the-lowering-visitor-descends-the-ast-top-down)                                                               | undocumented-behavior | "The lowering visitor descends the AST top-down" — the doc names the algorithmic style but does not list any user-observable consequence (e.g. ordering of nameHint decoration emission). An observability hook would let an agent test it.                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                       |
| [#diagnostics-during-lowering](../../../design/pipeline/04-ast-to-ir.md#diagnostics-during-lowering)                                                                                                     | missing-example       | The section names `Diagnostics::UnsupportedAssignmentTarget` for an assignment LHS the lowering switch cannot encode, but gives neither a shader construct that reaches that switch arm nor the diagnostic's E-code, so no DIAGNOSTIC_TEST can anchor to it.                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Add a minimal `.slang` example that triggers `UnsupportedAssignmentTarget` and quote the emitted `error E####:` line so a test can pin the code.                                      |
| [#generateirforspecializedcomponenttype](../../../design/pipeline/04-ast-to-ir.md#generateirforspecializedcomponenttype)                                                                                 | undocumented-behavior | `generateIRForSpecializedComponentType` and `generateIRForTypeConformance` are described as entry points but the doc does not name a `.slang`-observable surface that triggers each path. They are reachable only through C++ API.                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                       |
| [#lower-to-ir](../../../design/pipeline/04-ast-to-ir.md#lower-to-ir)                                                                                                                                     | undocumented-behavior | The doc says global parameters carry "layout intent" markers, but does not state what those markers look like in the `### LOWER-TO-IR:` stage (the layout decoration appears in later stages). A row of the form "global params carry decoration X at lowering" would let an agent test it; otherwise the topic belongs to `pipeline/04c-layout-ir`.                                                                                                                                                                                                                                                                                                                                                           |                                                                                                                                                                                       |
| [#element-types-and-storage-shapes](../../../design/pipeline/04-ast-to-ir.md#element-types-and-storage-shapes)                                                                                           | undocumented-behavior | **Type-lowering claims are implicit rather than enumerated.** The doc's table only names which AST-family produces which IR-family (e.g. `StructDecl -> IRStructType`). It does not enumerate the per-scalar-type IR-side spellings that lowering must preserve — `Int8`/`UInt8`/`Int16`/`UInt16`/`Int64`/`UInt64`/`Half`/`Double`, vector/array/matrix composition with each, and the rectangular matrix `Mat(<elem>, R : Int, C : Int, 0 : Int)` shape with row/col order. A "Element types and storage shapes" subsection under "Mapping AST constructs to IR" — or a cross-reference to `cross-cutting/ir-instructions.md` — would let agents anchor tests for these without stretching the existing rows. |                                                                                                                                                                                       |
| [#optionalt](../../../design/pipeline/04-ast-to-ir.md#optionalt)                                                                                                                                         | undocumented-behavior | **`Optional<T>` and `Tuple<...>` are not in the AST-family table.** Optional lowers to `Optional(<T>)` and Tuple to `tuple_type(...)`; both are observable through `-dump-ir`. The doc references the hash-consing rules in `design/ir.md` but no row in the lowering table names these generic-composite types, even though their syntax is part of the documented surface in `pipeline/03-semantic-check`.                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                       |
| [#parameterblockt-vardecl---irglobalparam-of-type-parameterblockt](../../../design/pipeline/04-ast-to-ir.md#parameterblockt-vardecl---irglobalparam-of-type-parameterblockt)                             | undocumented-behavior | **`ParameterBlock<T>` lowering is not mentioned by name.** The doc says global VarDecls become `IRGlobalVar`, but `ParameterBlock(%T)` is a distinct IR type, not a plain global. A row "ParameterBlock<T> VarDecl -> IRGlobalParam of type `ParameterBlock(%T)`" would close this gap.                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                       |
| [#typecastexpr---family-of-cast-pure-value-insts](../../../design/pipeline/04-ast-to-ir.md#typecastexpr---family-of-cast-pure-value-insts)                                                               | undocumented-behavior | **Cast lowering is illustrated by name but not by family.** The doc table mentions `BinaryExpr -> IRAdd/IRMul/IREq, ...`. Explicit type-cast lowering follows a parallel family — `floatCast`, `intCast`, `castFloatToInt`, `castIntToFloat` — with one opcode per source/dest type family. A row "TypeCastExpr -> family of cast pure-value insts" would tie these to the doc directly; the bundle currently anchors them under the more general "Mapping AST constructs to IR" header.                                                                                                                                                                                                                       |                                                                                                                                                                                       |
| [#variadic-pack-count-witnesses](../../../design/pipeline/04-ast-to-ir.md#variadic-pack-count-witnesses)                                                                                                 | missing-example       | The section describes the lowering of `GenericVariadicPackCountConstraintDecl` (hidden `WitnessTableType(void)` param, cached concrete proof-only witness table) but shows no Slang source example of a variadic generic carrying a `countof(Pack) == Count` constraint, so a test cannot anchor to a concrete surface spelling.                                                                                                                                                                                                                                                                                                                                                                               | Include a minimal variadic-generic shader with the count constraint plus the LOWER-TO-IR dump lines it produces (the hidden param and the proof-only witness table).                  |
| [#builtin-operators-bypass-call-lowering](../../../design/pipeline/04-ast-to-ir.md#builtin-operators-bypass-call-lowering)                                                                               | missing-example       | The compile-time paragraph says a `BuiltinOperationIntVal` lowers to hoistable `constexpr*` opcodes, but no example shader is given whose LOWER-TO-IR dump surfaces a `constexpr*` inst; the `ir-reference/values` bundle independently records that no reliable surface is documented.                                                                                                                                                                                                                                                                                                                                                                                                                        | Add a minimal generic (e.g. a `let N : int` parameter used in a non-polynomial constant expression such as `N / 2`) together with the dump line showing the resulting `constexprDiv`. |
