Files
TheRock/compiler/spirv-llvm-translator/docs/NonSemantic.AuxData.asciidoc
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

386 lines
14 KiB
Plaintext

SPIR-V NonSemantic AuxData Instructions
=======================================
Version 1.00
Contact
-------
To report problems with this extension, please open a new issue at:
https://github.com/KhronosGroup/SPIRV-LLVM-Translator
Contributors
------------
- Nick Sarnie, Intel
- Dmitry Sidorov, AMD
Notice
------
Copyright (c) 2026 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Status
------
- Complete draft. Defined and consumed by the SPIRV-LLVM-Translator;
not formally ratified by the SPIR-V Working Group.
Version
-------
[width="40%",cols="25,25"]
|========================================
| Last Modified Date | 2026-05-05
| Revision | 2
|========================================
Dependencies
------------
This extension is written against the SPIR-V Specification,
Version 1.6 Revision 7.
This instruction set requires either SPIR-V 1.6 or *SPV_KHR_non_semantic_info* extension.
Overview
--------
The *NonSemantic.AuxData* extended instruction set encodes auxiliary
data attached to LLVM IR `Function` and `GlobalVariable` objects
specifically, LLVM *attributes* and LLVM *metadata*, so that this
information can survive a round trip through SPIR-V and be restored
on reverse translation.
The information described by these instructions is, by construction,
*non-semantic*: a SPIR-V consumer that does not understand or does not
care about LLVM-level annotations may safely strip every instruction
in this set without changing the meaning of the module. The set exists
purely to act as a transparent transport for tooling that needs to
preserve LLVM metadata (for example, frontend or middle-end
contracts expressed via attribute/metadata strings) across a SPIR-V
boundary.
Import this extended instruction set using an `OpExtInstImport`
"NonSemantic.AuxData" instruction.
Terminology
-----------
The terms below are used as defined in the LLVM Language Reference
Manual (https://llvm.org/docs/LangRef.html):
- *Function attribute* / *Global variable attribute* - an attribute
attached to an LLVM `Function` or `GlobalVariable`. May be either
an enum-kind attribute (e.g. `nounwind`, `readonly`) or a string
attribute, with or without a string value;
- *Function metadata* / *global variable metadata* - a named LLVM
`MDNode` attached to a `Function` or `GlobalVariable`. The node's
operands are an ordered list, each of which is either an `MDString`
or a `ValueAsMetadata` wrapping a constant.
- *Linkage type* - the linkage classification of an LLVM `GlobalValue`,
as enumerated by `llvm::GlobalValue::LinkageTypes` and described in
the "Linkage Types" section of the LLVM Language Reference Manual.
The phrase "global object" refers collectively to either an LLVM
`Function` or an LLVM `GlobalVariable`.
1. Binary Form
--------------
All instructions in this set:
- have a 'Result Type' that must be *OpTypeVoid*;
- produce a 'Result <id>' that is not consumed by any other
instruction;
- have no associated capability and require no capability beyond
what is required to use `OpExtInst` against a non-semantic
extended instruction set;
- may appear at module scope, after all type, constant, and global
declarations they reference have been declared, in the locations
permitted for non-semantic instructions by *SPV_KHR_non_semantic_info*.
A producer should emit all *NonSemantic.AuxData* instructions in the
section of the module reserved for debug / non-semantic instructions
and must emit every operand 'OpString' and operand 'OpConstant' before the
*NonSemantic.AuxData* instruction that uses it.
A producer must not use this set to encode information that is
already representable through, and is in fact represented through,
another SPIR-V mechanism. In particular, the SPIRV-LLVM-Translator
deliberately does *not* emit *NonSemantic.AuxData* instructions for:
- LLVM metadata named `spirv.Decorations` and
`spirv.ParameterDecorations` (these are already lowered to native
*OpDecorate* / *OpMemberDecorate* chains);
- LLVM debug-info metadata (the `!dbg` attachment, kind
`LLVMContext::MD_dbg`), which is encoded via `OpLine`,
*NonSemantic.Shader.DebugInfo.100* / *OpenCL.DebugInfo.100*, or
similar facilities.
A consumer must tolerate the absence of any individual
*NonSemantic.AuxData* instruction; the set has no internal ordering
or dependency requirements between its own instructions.
Enumeration
~~~~~~~~~~~
The following table lists the instruction numbers assigned by this
extended instruction set:
[width="60%"]
|========================================
| Instruction number | Instruction name
| 0 | <<NonSemanticAuxDataFunctionMetadata,*NonSemanticAuxDataFunctionMetadata*>>
| 1 | <<NonSemanticAuxDataFunctionAttribute,*NonSemanticAuxDataFunctionAttribute*>>
| 2 | <<NonSemanticAuxDataGlobalVariableMetadata,*NonSemanticAuxDataGlobalVariableMetadata*>>
| 3 | <<NonSemanticAuxDataGlobalVariableAttribute,*NonSemanticAuxDataGlobalVariableAttribute*>>
| 4 | <<NonSemanticAuxDataLinkage,*NonSemanticAuxDataLinkage*>>
|========================================
[[LinkageType]]
Linkage Type
^^^^^^^^^^^^
The 'Linkage Type' operand of the
<<NonSemanticAuxDataLinkage,*NonSemanticAuxDataLinkage*>> instruction
is the '<id>' of a 32-bit integer *OpConstant* whose value is one of
the entries in the table below. The set of recognized values may grow
in future revisions of this specification; values not listed here are
reserved. A consumer that does not recognize a 'Linkage Type' value
must ignore the enclosing instruction.
[width="80%",cols="1,3,4"]
|========================================
| Value | Name | Meaning
| 0 | *AvailableExternally* | The target has LLVM `available_externally` linkage. The definition is provided for the consumer's benefit (for example, to enable inlining) but is not emitted as a separate symbol; consumers that lower the SPIR-V module back to LLVM IR should set this linkage on the corresponding `GlobalValue` after reverse translation, and should not consider the definition to participate in linking.
|========================================
Instructions
~~~~~~~~~~~~
[cols="2*1,3*2,1,3,3,3"]
|======
9+a|[[NonSemanticAuxDataFunctionAttribute]]*NonSemanticAuxDataFunctionAttribute* +
+
Record one LLVM-IR function attribute attached to an `OpFunction`. +
+
'Result Type' must be *OpTypeVoid*. +
+
'Target' is the '<id>' of the *OpFunction* the attribute is attached
to. +
+
'Attribute Name' is the '<id>' of an *OpString*. For LLVM string-kind
attributes (`AttributeImpl::isStringAttribute()` is true) it contains
the attribute key exactly as it appears in the LLVM module
(for example `"sycl-unique-id"`, `"foo"`). For LLVM enum-kind
attributes (for example `nounwind`, `readonly`) it contains the
attribute spelling as produced by `llvm::Attribute::getNameFromAttrKind`
(for example `"nounwind"`). +
+
'Attribute Value' is the '<id>' of an *OpString* holding the string
value associated with a string-kind attribute (for example `"32"` in
`"sycl-device-global-size"="32"`). 'Attribute Value' must be omitted
when the source attribute has no value (for example `"foo"` or any
enum-kind attribute), and must be present otherwise. +
+
For an LLVM attribute that is neither a string-kind attribute nor a
plain enum-kind attribute (for example a typed or integer attribute
that has no compact textual key/value form), the producer shall emit
'Attribute Name' as the '<id>' of an *OpString* containing the full
textual rendering returned by `llvm::Attribute::getAsString()`, and
shall omit 'Attribute Value'. A consumer encountering such a form
should treat the entire string as an opaque attribute spelling.
| 7 or 8 | 12 | '<id>' +
'Result Type' | 'Result <id>' | '<id> Set' | 1
| '<id>' 'Target'
| '<id>' 'Attribute Name'
| Optional +
'<id>' 'Attribute Value'
|======
[cols="2*1,3*2,1,3,3,3"]
|======
9+a|[[NonSemanticAuxDataGlobalVariableAttribute]]*NonSemanticAuxDataGlobalVariableAttribute* +
+
Record one LLVM-IR attribute attached to a global variable. +
+
'Result Type' must be *OpTypeVoid*. +
+
'Target' is the '<id>' of the *OpVariable* (declared at module scope)
the attribute is attached to. +
+
'Attribute Name' and 'Attribute Value' have the same form, the same
encoding rules, and the same optionality rules as the corresponding
operands of <<NonSemanticAuxDataFunctionAttribute,*NonSemanticAuxDataFunctionAttribute*>>.
| 7 or 8 | 12 | '<id>' +
'Result Type' | 'Result <id>' | '<id> Set' | 3
| '<id>' 'Target'
| '<id>' 'Attribute Name'
| Optional +
'<id>' 'Attribute Value'
|======
[cols="2*1,3*2,1,3,3,3"]
|======
9+a|[[NonSemanticAuxDataFunctionMetadata]]*NonSemanticAuxDataFunctionMetadata* +
+
Record one named LLVM-IR metadata attachment on an `OpFunction`. +
+
'Result Type' must be *OpTypeVoid*. +
+
'Target' is the '<id>' of the *OpFunction* the metadata is attached
to. +
+
'Metadata Name' is the '<id>' of an *OpString* containing the metadata
kind name, exactly as it appears in the LLVM module (for example
`"foo"`, `"absolute_symbol"`, `"prof"`). +
+
'Metadata Value' operands form a variable-length, ordered list
mirroring the operand list of the source `MDNode`. Each operand
shall be one of: +
+
- the '<id>' of an *OpString*, encoding an `MDString` operand whose
value is that string; or +
- the '<id>' of any other SPIR-V value (typically an *OpConstant* or
*OpConstantComposite*), encoding a `ValueAsMetadata` operand
wrapping the corresponding LLVM constant. The translation between
the SPIR-V value and the LLVM constant follows the normal forward
/ reverse rules of the surrounding SPIR-V value translation. +
+
The number of 'Metadata Value' operands MAY be zero (for an empty
`MDNode`). It is unbounded otherwise.
A consumer must skip a *NonSemanticAuxDataFunctionMetadata*
instruction whose 'Metadata Name' is already attached to 'Target'
through some other reverse-translation path, to avoid creating
duplicate metadata attachments.
| 7 + 'variable' | 12 | '<id>' +
'Result Type' | 'Result <id>' | '<id> Set' | 0
| '<id>' 'Target'
| '<id>' 'Metadata Name'
| 'Metadata Value', 'Metadata Value', ... (zero or more)
|======
[cols="2*1,3*2,1,3,3,3"]
|======
9+a|[[NonSemanticAuxDataGlobalVariableMetadata]]*NonSemanticAuxDataGlobalVariableMetadata* +
+
Record one named LLVM-IR metadata attachment on a global variable. +
+
'Result Type' must be *OpTypeVoid*. +
+
'Target' is the '<id>' of the *OpVariable* (declared at module scope)
the metadata is attached to. +
+
'Metadata Name' and 'Metadata Value' operands have the same form,
the same encoding rules, the same exclusions, and the same
duplicate-skip recommendation as the corresponding operands of
<<NonSemanticAuxDataFunctionMetadata,*NonSemanticAuxDataFunctionMetadata*>>.
| 7 + 'variable' | 12 | '<id>' +
'Result Type' | 'Result <id>' | '<id> Set' | 2
| '<id>' 'Target'
| '<id>' 'Metadata Name'
| 'Metadata Value', 'Metadata Value', ... (zero or more)
|======
[cols="2*1,3*2,1,3,3"]
|======
8+a|[[NonSemanticAuxDataLinkage]]*NonSemanticAuxDataLinkage* +
+
Record the LLVM-IR linkage type of a global object. +
+
'Result Type' must be *OpTypeVoid*. +
+
'Target' is the '<id>' of the *OpFunction* or of the module-scope
*OpVariable* whose linkage is being recorded. Linkage is a property
of the LLVM `GlobalValue` base class, so the same instruction is used
regardless of which kind of global object 'Target' refers to. +
+
At most one *NonSemanticAuxDataLinkage* instruction should reference
any given 'Target'; if a producer emits more than one, a consumer
must honor only the last one in module order. +
+
'Linkage Type' is the '<id>' of a 32-bit integer *OpConstant* whose
value is taken from the <<LinkageType,*Linkage Type*>> table. +
+
A producer must not emit this instruction for the default LLVM
linkage (`external`); the absence of a *NonSemanticAuxDataLinkage*
record on a global object means the object carries the linkage that
the SPIR-V module otherwise implies. A consumer that sees a
'Linkage Type' value it does not recognize must silently ignore the
instruction.
| 7 | 12 | '<id>' +
'Result Type' | 'Result <id>' | '<id> Set' | 4
| '<id>' 'Target'
| '<id>' 'Linkage Type'
|======
2. Encoding Notes
-----------------
This section is informative; it is not part of the normative content
of the specification.
Round-trip behaviour
~~~~~~~~~~~~~~~~~~~~
The set is designed to be lossless on a producer/consumer pair that
both opt in to its use. For each global object the SPIRV-LLVM-Translator
walks `Function::getAttributes().getFnAttrs()` (or
`GlobalVariable::getAttributes()`) once and emits one
`...Attribute` instruction per attribute, then walks
`GlobalObject::getAllMetadata()` once and emits one `...Metadata`
instruction per metadata attachment, in the order the LLVM data
structures yield them. The reverse path performs the inverse
operation, calling the LLVM API that adds an attribute or sets a
metadata kind on the corresponding global object.
The specification sets no restrictions regarding how much
`NonSemanticAuxData` instructions can annotate a single 'Target' nor
it forbids a case of duplicated information being attached to the
'Target'. It is SPIR-V consumer duty to ensure LLVM module validity
after the round-trip.
Interaction with attribute-kind translation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some LLVM enum-kind attributes are also produced as a side effect of
unrelated reverse translation (for example, `nounwind` is set on
intrinsic-like callees regardless of *NonSemantic.AuxData*). When the
reverse translator processes a `...Attribute` instruction whose
'Attribute Name' resolves to an `Attribute::AttrKind` already present
on the target, it must skip the instruction so as not to duplicate
the attribute. The same skip rule applies for string-kind attributes
already present on the target.
Issues
------
None.
Revision History
----------------
[cols="5,15,15,70"]
[grid="rows"]
[options="header"]
|========================================
|Rev|Date|Author|Changes
|1|xxxx-xx-xx|Nick Sarnie|Initial draft
|2|2026-05-05|Dmitry Sidorov|Finalize spec, add available_externally
|========================================