Skip to content

Conversation

jdnk
Copy link
Contributor

@jdnk jdnk commented Jun 5, 2025

This PR adds a registry containing enumerator values of device targets, features and architectures to be used with the SPV_INTEL_function_variants extension (and other extensions that find it useful). See the README file for details.

The purpose of the PR is to iterate on the registry format before filling in all the entries.

Targets and features come from inspecting compiler output (llc --version and llc --mtriple=<target> -mattr=help). A bulk of the architectures I took directly from sycl_ext_oneapi_device_architecture (mostly the GPUs). Others I added by hand (eg. Intel and ARM CPUs).

Open questions:

  • There could be other ways how to categorize the Intel CPU architectures. I opted strictly for the microarchitecture, another possibility is by the processor name / codename (eg. Meteor Lake instead of Redwood Cove + Crestmont). This may apply for other architectures as well.
  • Should we add only Intel architectures and let other vendors fill their own? For adoption, it would be better to add as many as we can, but we risk landing on architecture ordering different from what the vendor would prefer.
    • During version 0 we can pre-add values for other vendors and let vendors take over before "freezing" version 1.

@jdnk jdnk requested a review from a team as a code owner June 5, 2025 09:35
@jdnk jdnk changed the title Add initial draft of the targets registry [SYCL][Doc] Add initial draft of the targets registry Jun 5, 2025
@jdnk
Copy link
Contributor Author

jdnk commented Jun 23, 2025

@gmlueck Would you be able to check this?

@jdnk
Copy link
Contributor Author

jdnk commented Jul 10, 2025

Would it be possible to get a review on this?

MrSidims pushed a commit to KhronosGroup/SPIRV-LLVM-Translator that referenced this pull request Jul 15, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \ 
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
vmaksimo pushed a commit that referenced this pull request Jul 29, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.

Original commit:
KhronosGroup/SPIRV-LLVM-Translator@aaa23785dcbd7ca
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
jdnk added a commit to jdnk/SPIRV-LLVM-Translator that referenced this pull request Aug 13, 2025
This PR implements
[SPV_INTEL_function_variants](https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc).
It adds an optional SPIR-V to SPIR-V specialization pass that converts a
multitarget module into a targeted one.

The multitarget module does not have a LLVM IR representation, the
extension only describes the specialization algorithm that takes place
before converting the SPIR-V module into LLVM-IR. For this reason, it is
only implemented as a part of SPIRVReader and not SPIRVWriter.

The specialization is controlled by the user supplying the target device
category, family, architecture, target ISA, supported features and/or
supported capabilities via CLI flags. For example, to specialize for an
Intel x86_64 CPU with Lion Cove microarchitecture that supports SSE,
SSE2, SSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX2 and AVX512f features and
Addresses, Linkage, Kernel, Int64 and Int8 capabilities, the user needs
to provide the following flags:
```
llvm-spirv -r \
  --spirv-ext=+SPV_INTEL_function_variants \
  --fnvar-spec-enable \
  --fnvar-spv-out targeted.spv \
  --fnvar-category 1  --fnvar-family 1  --fnvar-arch 15 \
  --fnvar-target 4  --fnvar-features '4,5,6,7,8,9,10,11,12' \
  --fnvar-capabilities '4,5,6,11,39' \
  multitarget.spv -o targeted.bc
```
Omitting a flag means that the target device supports all values for the
flag. For example, in the above example, leaving out the
`--fnvar-features` flag means that that the target device supports all
features available for the x86_64 target.

The integer values passed to the CLI flags are taken from a proposed
[targets _registry_](intel/llvm#18822)
accompanying the extension. (Capabilities correspond directly to the
values defined in the SPIR-V specification). During the specialization
pass, the specialization pass compares these CLI-supplied integers with
the operands of `OpSpecConstantTargetINTEL`,
`OpSpecConstantArchitectureINTEL` and `OpSpecConstantCapabilitiesINTEL`
instructions in the input multitarget module, converts these
instructions to constant true/false and proceeds with the specialization
according to the rules described in the extension.

Providing the CLI values as raw integer is not the most user friendly,
and the translator does not validate the values in any way (eg.,
checking that feature X is allowed for target Y). This can be improved
after the _registry_ is merged and more mature (version >0).

Note: `--spirv-debug` can be used to print out details about what's
happening when evaluating the above spec constants. It's useful for
getting an insight into why a certain function variant got selected if
the selection does not match the expected outcome.
Copy link
Contributor

@bashbaug bashbaug left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, I focused more on the target registry logistics and less on its content.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely not something that needs to be changed in this PR, but you may want to investigate something like the Mako template library to improve maintainability in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good idea. The current generation script is quite bare-bones, but it will need something more robust going forward. I added it to a new TODO section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you thought about including a license in this source file?

In a subsequent PR, it may be helpful to generate several different types of header files, such as a pure C header file like this one and a header file that uses C++ features.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I haven't thought about license, but there should be one. Perhaps not only in the header but for all files?

I saw SPIRV-Headers is licensed by CC-BY-4.0 and MIT. Would MIT with "The Khronos Group Inc." copyright be appropriate here?

@jdnk jdnk changed the title [SYCL][Doc] Add initial draft of the targets registry [SYCL][Doc] Add initial draft of the device registry Aug 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants