diff mbox series

[2/3] spirv-tools: Add SPV_INTEL_function_variants

Message ID 20250819010128.3519760-2-raj.khem@gmail.com
State New
Headers show
Series [1/3] spirv-headers: Add SPV_INTEL_function_variants | expand

Commit Message

Khem Raj Aug. 19, 2025, 1:01 a.m. UTC
Needed for compiling clang-21

Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 ...on_variants-basic-asm-dis-support-61.patch | 289 ++++++++++++++++++
 .../spir/spirv-tools_1.4.321.0.bb             |   1 +
 2 files changed, 290 insertions(+)
 create mode 100644 meta/recipes-graphics/spir/spirv-tools/0001-SPV_INTEL_function_variants-basic-asm-dis-support-61.patch
diff mbox series

Patch

diff --git a/meta/recipes-graphics/spir/spirv-tools/0001-SPV_INTEL_function_variants-basic-asm-dis-support-61.patch b/meta/recipes-graphics/spir/spirv-tools/0001-SPV_INTEL_function_variants-basic-asm-dis-support-61.patch
new file mode 100644
index 00000000000..d4ca23c7295
--- /dev/null
+++ b/meta/recipes-graphics/spir/spirv-tools/0001-SPV_INTEL_function_variants-basic-asm-dis-support-61.patch
@@ -0,0 +1,289 @@ 
+From 28a883ba4c67f58a9540fb0651c647bb02883622 Mon Sep 17 00:00:00 2001
+From: David Neto <dneto@google.com>
+Date: Wed, 25 Jun 2025 11:27:23 -0400
+Subject: [PATCH] SPV_INTEL_function_variants: basic asm, dis support (#6195)
+
+The challenging part is that there are instructions that
+take zero or more Capability operands.  So we have to introduce
+SPV_TYPE_OPERAND_VARIABLE_CAPABILITY and SPV_TYPE_OPERAND_OPTIONAL_CAPABILITY.
+
+Remove deprecated enums for the first and last variable or optional
+enums.
+Upstream-Status: Backport [https://github.com/KhronosGroup/SPIRV-Tools/commit/28a883ba4c67f58a9540fb0651c647bb02883622]
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ DEPS                                   |  2 +-
+ include/spirv-tools/libspirv.h         | 48 +++++++----------
+ source/binary.cpp                      |  3 ++
+ source/disassemble.cpp                 |  1 +
+ source/operand.cpp                     |  7 +++
+ test/text_to_binary.extension_test.cpp | 73 ++++++++++++++++++++++++++
+ utils/ggt.py                           |  3 +-
+ 7 files changed, 107 insertions(+), 30 deletions(-)
+
+diff --git a/DEPS b/DEPS
+index e25ca513..511fd718 100644
+--- a/DEPS
++++ b/DEPS
+@@ -14,7 +14,7 @@ vars = {
+ 
+   're2_revision': 'c84a140c93352cdabbfb547c531be34515b12228',
+ 
+-  'spirv_headers_revision': '2a611a970fdbc41ac2e3e328802aed9985352dca',
++  'spirv_headers_revision': '9e3836d7d6023843a72ecd3fbf3f09b1b6747a9e',
+ 
+   'mimalloc_revision': '09a27098aa6e9286518bd9c74e6ffa7199c3f04e',
+ }
+diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
+index a2a032a0..2a604e94 100644
+--- a/include/spirv-tools/libspirv.h
++++ b/include/spirv-tools/libspirv.h
+@@ -189,36 +189,24 @@ typedef enum spv_operand_type_t {
+   SPV_OPERAND_TYPE_MEMORY_ACCESS,          // SPIR-V Sec 3.26
+   SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE,  // SPIR-V Sec 3.FSR
+ 
+-// NOTE: New concrete enum values should be added at the end.
+-
+-// The "optional" and "variable"  operand types are only used internally by
+-// the assembler and the binary parser.
+-// There are two categories:
+-//    Optional : expands to 0 or 1 operand, like ? in regular expressions.
+-//    Variable : expands to 0, 1 or many operands or pairs of operands.
+-//               This is similar to * in regular expressions.
+-
+-// NOTE: These FIRST_* and LAST_* enum values are DEPRECATED.
+-// The concept of "optional" and "variable" operand types are only intended
+-// for use as an implementation detail of parsing SPIR-V, either in text or
+-// binary form.  Instead of using enum ranges, use characteristic function
+-// spvOperandIsConcrete.
+-// The use of enum value ranges in a public API makes it difficult to insert
+-// new values into a range without also breaking binary compatibility.
+-//
+-// Macros for defining bounds on optional and variable operand types.
+-// Any variable operand type is also optional.
+-// TODO(dneto): Remove SPV_OPERAND_TYPE_FIRST_* and SPV_OPERAND_TYPE_LAST_*
+-#define FIRST_OPTIONAL(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE = ENUM
+-#define FIRST_VARIABLE(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE = ENUM
+-#define LAST_VARIABLE(ENUM)                         \
+-  ENUM, SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE = ENUM, \
+-        SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE = ENUM
++  // NOTE: New concrete enum values should be added at the end.
++
++  // The "optional" and "variable"  operand types are only used internally by
++  // the assembler and the binary parser.
++  // There are two categories:
++  //    Optional : expands to 0 or 1 operand, like ? in regular expressions.
++  //    Variable : expands to 0, 1 or many operands or pairs of operands.
++  //               This is similar to * in regular expressions.
++
++  // Use characteristic function spvOperandIsConcrete to classify the
++  // operand types; when it returns false, the operand is optional or variable.
++  //
++  // Any variable operand type is also optional.
+ 
+   // An optional operand represents zero or one logical operands.
+   // In an instruction definition, this may only appear at the end of the
+   // operand types.
+-  FIRST_OPTIONAL(SPV_OPERAND_TYPE_OPTIONAL_ID),
++  SPV_OPERAND_TYPE_OPTIONAL_ID,
+   // An optional image operand type.
+   SPV_OPERAND_TYPE_OPTIONAL_IMAGE,
+   // An optional memory access type.
+@@ -243,7 +231,7 @@ typedef enum spv_operand_type_t {
+   // A variable operand represents zero or more logical operands.
+   // In an instruction definition, this may only appear at the end of the
+   // operand types.
+-  FIRST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID),
++  SPV_OPERAND_TYPE_VARIABLE_ID,
+   SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER,
+   // A sequence of zero or more pairs of (typed literal integer, Id).
+   // Expands to zero or more:
+@@ -251,7 +239,7 @@ typedef enum spv_operand_type_t {
+   // where the literal number must always be an integer of some sort.
+   SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID,
+   // A sequence of zero or more pairs of (Id, Literal integer)
+-  LAST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER),
++  SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER,
+ 
+   // The following are concrete enum types from the DebugInfo extended
+   // instruction set.
+@@ -343,6 +331,10 @@ typedef enum spv_operand_type_t {
+   SPV_OPERAND_TYPE_TENSOR_OPERANDS,
+   SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS,
+ 
++  // SPV_INTEL_function_variants
++  SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY,
++  SPV_OPERAND_TYPE_VARIABLE_CAPABILITY,
++
+   // This is a sentinel value, and does not represent an operand type.
+   // It should come last.
+   SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,
+diff --git a/source/binary.cpp b/source/binary.cpp
+index 180d0a99..8e4d899f 100644
+--- a/source/binary.cpp
++++ b/source/binary.cpp
+@@ -636,6 +636,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
+     } break;
+ 
+     case SPV_OPERAND_TYPE_CAPABILITY:
++    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
+     case SPV_OPERAND_TYPE_EXECUTION_MODEL:
+     case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
+     case SPV_OPERAND_TYPE_MEMORY_MODEL:
+@@ -689,6 +690,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
+         parsed_operand.type = SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT;
+       if (type == SPV_OPERAND_TYPE_OPTIONAL_FPENCODING)
+         parsed_operand.type = SPV_OPERAND_TYPE_FPENCODING;
++      if (type == SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY)
++        parsed_operand.type = SPV_OPERAND_TYPE_CAPABILITY;
+ 
+       const spvtools::OperandDesc* entry = nullptr;
+       if (spvtools::LookupOperand(type, word, &entry)) {
+diff --git a/source/disassemble.cpp b/source/disassemble.cpp
+index 2d9bb0ff..4267333a 100644
+--- a/source/disassemble.cpp
++++ b/source/disassemble.cpp
+@@ -907,6 +907,7 @@ void InstructionDisassembler::EmitOperand(std::ostream& stream,
+       stream << '"';
+     } break;
+     case SPV_OPERAND_TYPE_CAPABILITY:
++    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
+     case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
+     case SPV_OPERAND_TYPE_EXECUTION_MODEL:
+     case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
+diff --git a/source/operand.cpp b/source/operand.cpp
+index c635c72d..d7fc535c 100644
+--- a/source/operand.cpp
++++ b/source/operand.cpp
+@@ -111,6 +111,7 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
+     case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
+       return "kernel profiling info";
+     case SPV_OPERAND_TYPE_CAPABILITY:
++    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
+       return "capability";
+     case SPV_OPERAND_TYPE_RAY_FLAGS:
+       return "ray flags";
+@@ -394,6 +395,7 @@ bool spvOperandIsOptional(spv_operand_type_t type) {
+     case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
+     case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
+     case SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS:
++    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
+       return true;
+     default:
+       break;
+@@ -408,6 +410,7 @@ bool spvOperandIsVariable(spv_operand_type_t type) {
+     case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
+     case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
+     case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
++    case SPV_OPERAND_TYPE_VARIABLE_CAPABILITY:
+       return true;
+     default:
+       break;
+@@ -439,6 +442,10 @@ bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
+       pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
+       pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
+       return true;
++    case SPV_OPERAND_TYPE_VARIABLE_CAPABILITY:
++      pattern->push_back(type);
++      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY);
++      return true;
+     default:
+       break;
+   }
+diff --git a/test/text_to_binary.extension_test.cpp b/test/text_to_binary.extension_test.cpp
+index 65079d1b..39accfc1 100644
+--- a/test/text_to_binary.extension_test.cpp
++++ b/test/text_to_binary.extension_test.cpp
+@@ -1495,5 +1495,78 @@ INSTANTIATE_TEST_SUITE_P(
+                                SaturatedToLargestFloat8NormalConversionEXT)})},
+         })));
+ 
++// SPV_INTEL_function_variants
++// https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc
++INSTANTIATE_TEST_SUITE_P(
++    SPV_INTEL_function_variants, ExtensionRoundTripTest,
++    Combine(
++        Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_6),
++        ValuesIn(std::vector<AssemblyCase>{
++            {"OpExtension \"SPV_INTEL_function_variants\"\n",
++             MakeInstruction(spv::Op::OpExtension,
++                             MakeVector("SPV_INTEL_function_variants"))},
++            {"OpCapability SpecConditionalINTEL\n",
++             MakeInstruction(
++                 spv::Op::OpCapability,
++                 {(uint32_t)spv::Capability::SpecConditionalINTEL})},
++            {"OpCapability FunctionVariantsINTEL\n",
++             MakeInstruction(
++                 spv::Op::OpCapability,
++                 {(uint32_t)spv::Capability::FunctionVariantsINTEL})},
++            {"OpDecorate %1 ConditionalINTEL %2\n",
++             MakeInstruction(spv::Op::OpDecorate,
++                             {1, (uint32_t)spv::Decoration::ConditionalINTEL,
++                              2})},
++
++            {"OpConditionalExtensionINTEL %1 \"foo\"\n",
++             MakeInstruction(spv::Op::OpConditionalExtensionINTEL, {1},
++                             MakeVector("foo"))},
++
++            {"OpConditionalEntryPointINTEL %1 Kernel %2 \"foo\"\n",
++             MakeInstruction(spv::Op::OpConditionalEntryPointINTEL,
++                             {1, (uint32_t)spv::ExecutionModel::Kernel, 2},
++                             MakeVector("foo"))},
++
++            {"OpConditionalCapabilityINTEL %1 Kernel\n",
++             MakeInstruction(spv::Op::OpConditionalCapabilityINTEL,
++                             {1, (uint32_t)spv::ExecutionModel::Kernel})},
++
++            {"%2 = OpSpecConstantTargetINTEL %1 42\n",
++             MakeInstruction(spv::Op::OpSpecConstantTargetINTEL, {1, 2, 42})},
++
++            {"%2 = OpSpecConstantTargetINTEL %1 42 99\n",
++             MakeInstruction(spv::Op::OpSpecConstantTargetINTEL,
++                             {1, 2, 42, 99})},
++
++            {"%2 = OpSpecConstantTargetINTEL %1 42 99 108\n",
++             MakeInstruction(spv::Op::OpSpecConstantTargetINTEL,
++                             {1, 2, 42, 99, 108})},
++
++            {"%2 = OpSpecConstantArchitectureINTEL %1 42 99 108 72\n",
++             MakeInstruction(spv::Op::OpSpecConstantArchitectureINTEL,
++                             {1, 2, 42, 99, 108, 72})},
++
++            {"%2 = OpSpecConstantCapabilitiesINTEL %1\n",
++             MakeInstruction(spv::Op::OpSpecConstantCapabilitiesINTEL, {1, 2})},
++
++            {"%2 = OpSpecConstantCapabilitiesINTEL %1 Kernel\n",
++             MakeInstruction(spv::Op::OpSpecConstantCapabilitiesINTEL,
++                             {1, 2, (uint32_t)spv::Capability::Kernel})},
++
++            {"%2 = OpSpecConstantCapabilitiesINTEL %1 Kernel Shader\n",
++             MakeInstruction(spv::Op::OpSpecConstantCapabilitiesINTEL,
++                             {1, 2, (uint32_t)spv::Capability::Kernel,
++                              (uint32_t)spv::Capability::Shader})},
++
++            {"%2 = OpConditionalCopyObjectINTEL %1 %3 %4\n",
++             MakeInstruction(spv::Op::OpConditionalCopyObjectINTEL,
++                             {1, 2, 3, 4})},
++
++            {"%2 = OpConditionalCopyObjectINTEL %1 %3 %4 %5 %6\n",
++             MakeInstruction(spv::Op::OpConditionalCopyObjectINTEL,
++                             {1, 2, 3, 4, 5, 6})},
++
++        })));
++
+ }  // namespace
+ }  // namespace spvtools
+diff --git a/utils/ggt.py b/utils/ggt.py
+index 258c1b00..45262ba8 100755
+--- a/utils/ggt.py
++++ b/utils/ggt.py
+@@ -242,7 +242,8 @@ class Grammar():
+                 'MatrixMultiplyAccumulateOperands',
+                 'RawAccessChainOperands',
+                 'FPEncoding',
+-                'TensorOperands']
++                'TensorOperands',
++                'Capability']
+ 
+     def dump(self) -> None:
+         self.context.dump()
diff --git a/meta/recipes-graphics/spir/spirv-tools_1.4.321.0.bb b/meta/recipes-graphics/spir/spirv-tools_1.4.321.0.bb
index 319b25b7f43..30c42e915f9 100644
--- a/meta/recipes-graphics/spir/spirv-tools_1.4.321.0.bb
+++ b/meta/recipes-graphics/spir/spirv-tools_1.4.321.0.bb
@@ -9,6 +9,7 @@  LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
 
 SRCREV = "33e02568181e3312f49a3cf33df470bf96ef293a"
 SRC_URI = "git://github.com/KhronosGroup/SPIRV-Tools.git;branch=main;protocol=https \
+           file://0001-SPV_INTEL_function_variants-basic-asm-dis-support-61.patch \
            "
 PE = "1"
 # These recipes need to be updated in lockstep with each other: