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
386 lines
14 KiB
Plaintext
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
|
|
|========================================
|