Skip to content

Commit 28a883b

Browse files
authored
SPV_INTEL_function_variants: basic asm, dis support (KhronosGroup#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.
1 parent 37da763 commit 28a883b

File tree

7 files changed

+107
-30
lines changed

7 files changed

+107
-30
lines changed

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ vars = {
1414

1515
're2_revision': 'c84a140c93352cdabbfb547c531be34515b12228',
1616

17-
'spirv_headers_revision': '2a611a970fdbc41ac2e3e328802aed9985352dca',
17+
'spirv_headers_revision': '9e3836d7d6023843a72ecd3fbf3f09b1b6747a9e',
1818

1919
'mimalloc_revision': '09a27098aa6e9286518bd9c74e6ffa7199c3f04e',
2020
}

include/spirv-tools/libspirv.h

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -189,36 +189,24 @@ typedef enum spv_operand_type_t {
189189
SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26
190190
SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, // SPIR-V Sec 3.FSR
191191

192-
// NOTE: New concrete enum values should be added at the end.
193-
194-
// The "optional" and "variable" operand types are only used internally by
195-
// the assembler and the binary parser.
196-
// There are two categories:
197-
// Optional : expands to 0 or 1 operand, like ? in regular expressions.
198-
// Variable : expands to 0, 1 or many operands or pairs of operands.
199-
// This is similar to * in regular expressions.
200-
201-
// NOTE: These FIRST_* and LAST_* enum values are DEPRECATED.
202-
// The concept of "optional" and "variable" operand types are only intended
203-
// for use as an implementation detail of parsing SPIR-V, either in text or
204-
// binary form. Instead of using enum ranges, use characteristic function
205-
// spvOperandIsConcrete.
206-
// The use of enum value ranges in a public API makes it difficult to insert
207-
// new values into a range without also breaking binary compatibility.
208-
//
209-
// Macros for defining bounds on optional and variable operand types.
210-
// Any variable operand type is also optional.
211-
// TODO(dneto): Remove SPV_OPERAND_TYPE_FIRST_* and SPV_OPERAND_TYPE_LAST_*
212-
#define FIRST_OPTIONAL(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE = ENUM
213-
#define FIRST_VARIABLE(ENUM) ENUM, SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE = ENUM
214-
#define LAST_VARIABLE(ENUM) \
215-
ENUM, SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE = ENUM, \
216-
SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE = ENUM
192+
// NOTE: New concrete enum values should be added at the end.
193+
194+
// The "optional" and "variable" operand types are only used internally by
195+
// the assembler and the binary parser.
196+
// There are two categories:
197+
// Optional : expands to 0 or 1 operand, like ? in regular expressions.
198+
// Variable : expands to 0, 1 or many operands or pairs of operands.
199+
// This is similar to * in regular expressions.
200+
201+
// Use characteristic function spvOperandIsConcrete to classify the
202+
// operand types; when it returns false, the operand is optional or variable.
203+
//
204+
// Any variable operand type is also optional.
217205

218206
// An optional operand represents zero or one logical operands.
219207
// In an instruction definition, this may only appear at the end of the
220208
// operand types.
221-
FIRST_OPTIONAL(SPV_OPERAND_TYPE_OPTIONAL_ID),
209+
SPV_OPERAND_TYPE_OPTIONAL_ID,
222210
// An optional image operand type.
223211
SPV_OPERAND_TYPE_OPTIONAL_IMAGE,
224212
// An optional memory access type.
@@ -243,15 +231,15 @@ typedef enum spv_operand_type_t {
243231
// A variable operand represents zero or more logical operands.
244232
// In an instruction definition, this may only appear at the end of the
245233
// operand types.
246-
FIRST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID),
234+
SPV_OPERAND_TYPE_VARIABLE_ID,
247235
SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER,
248236
// A sequence of zero or more pairs of (typed literal integer, Id).
249237
// Expands to zero or more:
250238
// (SPV_OPERAND_TYPE_TYPED_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID)
251239
// where the literal number must always be an integer of some sort.
252240
SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID,
253241
// A sequence of zero or more pairs of (Id, Literal integer)
254-
LAST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER),
242+
SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER,
255243

256244
// The following are concrete enum types from the DebugInfo extended
257245
// instruction set.
@@ -343,6 +331,10 @@ typedef enum spv_operand_type_t {
343331
SPV_OPERAND_TYPE_TENSOR_OPERANDS,
344332
SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS,
345333

334+
// SPV_INTEL_function_variants
335+
SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY,
336+
SPV_OPERAND_TYPE_VARIABLE_CAPABILITY,
337+
346338
// This is a sentinel value, and does not represent an operand type.
347339
// It should come last.
348340
SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,

source/binary.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
636636
} break;
637637

638638
case SPV_OPERAND_TYPE_CAPABILITY:
639+
case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
639640
case SPV_OPERAND_TYPE_EXECUTION_MODEL:
640641
case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
641642
case SPV_OPERAND_TYPE_MEMORY_MODEL:
@@ -689,6 +690,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
689690
parsed_operand.type = SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT;
690691
if (type == SPV_OPERAND_TYPE_OPTIONAL_FPENCODING)
691692
parsed_operand.type = SPV_OPERAND_TYPE_FPENCODING;
693+
if (type == SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY)
694+
parsed_operand.type = SPV_OPERAND_TYPE_CAPABILITY;
692695

693696
const spvtools::OperandDesc* entry = nullptr;
694697
if (spvtools::LookupOperand(type, word, &entry)) {

source/disassemble.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,7 @@ void InstructionDisassembler::EmitOperand(std::ostream& stream,
907907
stream << '"';
908908
} break;
909909
case SPV_OPERAND_TYPE_CAPABILITY:
910+
case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
910911
case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
911912
case SPV_OPERAND_TYPE_EXECUTION_MODEL:
912913
case SPV_OPERAND_TYPE_ADDRESSING_MODEL:

source/operand.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
111111
case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
112112
return "kernel profiling info";
113113
case SPV_OPERAND_TYPE_CAPABILITY:
114+
case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
114115
return "capability";
115116
case SPV_OPERAND_TYPE_RAY_FLAGS:
116117
return "ray flags";
@@ -394,6 +395,7 @@ bool spvOperandIsOptional(spv_operand_type_t type) {
394395
case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
395396
case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
396397
case SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS:
398+
case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
397399
return true;
398400
default:
399401
break;
@@ -408,6 +410,7 @@ bool spvOperandIsVariable(spv_operand_type_t type) {
408410
case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
409411
case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
410412
case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
413+
case SPV_OPERAND_TYPE_VARIABLE_CAPABILITY:
411414
return true;
412415
default:
413416
break;
@@ -439,6 +442,10 @@ bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
439442
pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
440443
pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
441444
return true;
445+
case SPV_OPERAND_TYPE_VARIABLE_CAPABILITY:
446+
pattern->push_back(type);
447+
pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY);
448+
return true;
442449
default:
443450
break;
444451
}

test/text_to_binary.extension_test.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,5 +1495,78 @@ INSTANTIATE_TEST_SUITE_P(
14951495
SaturatedToLargestFloat8NormalConversionEXT)})},
14961496
})));
14971497

1498+
// SPV_INTEL_function_variants
1499+
// https://github.com/intel/llvm/blob/sycl/sycl/doc/design/spirv-extensions/SPV_INTEL_function_variants.asciidoc
1500+
INSTANTIATE_TEST_SUITE_P(
1501+
SPV_INTEL_function_variants, ExtensionRoundTripTest,
1502+
Combine(
1503+
Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_6),
1504+
ValuesIn(std::vector<AssemblyCase>{
1505+
{"OpExtension \"SPV_INTEL_function_variants\"\n",
1506+
MakeInstruction(spv::Op::OpExtension,
1507+
MakeVector("SPV_INTEL_function_variants"))},
1508+
{"OpCapability SpecConditionalINTEL\n",
1509+
MakeInstruction(
1510+
spv::Op::OpCapability,
1511+
{(uint32_t)spv::Capability::SpecConditionalINTEL})},
1512+
{"OpCapability FunctionVariantsINTEL\n",
1513+
MakeInstruction(
1514+
spv::Op::OpCapability,
1515+
{(uint32_t)spv::Capability::FunctionVariantsINTEL})},
1516+
{"OpDecorate %1 ConditionalINTEL %2\n",
1517+
MakeInstruction(spv::Op::OpDecorate,
1518+
{1, (uint32_t)spv::Decoration::ConditionalINTEL,
1519+
2})},
1520+
1521+
{"OpConditionalExtensionINTEL %1 \"foo\"\n",
1522+
MakeInstruction(spv::Op::OpConditionalExtensionINTEL, {1},
1523+
MakeVector("foo"))},
1524+
1525+
{"OpConditionalEntryPointINTEL %1 Kernel %2 \"foo\"\n",
1526+
MakeInstruction(spv::Op::OpConditionalEntryPointINTEL,
1527+
{1, (uint32_t)spv::ExecutionModel::Kernel, 2},
1528+
MakeVector("foo"))},
1529+
1530+
{"OpConditionalCapabilityINTEL %1 Kernel\n",
1531+
MakeInstruction(spv::Op::OpConditionalCapabilityINTEL,
1532+
{1, (uint32_t)spv::ExecutionModel::Kernel})},
1533+
1534+
{"%2 = OpSpecConstantTargetINTEL %1 42\n",
1535+
MakeInstruction(spv::Op::OpSpecConstantTargetINTEL, {1, 2, 42})},
1536+
1537+
{"%2 = OpSpecConstantTargetINTEL %1 42 99\n",
1538+
MakeInstruction(spv::Op::OpSpecConstantTargetINTEL,
1539+
{1, 2, 42, 99})},
1540+
1541+
{"%2 = OpSpecConstantTargetINTEL %1 42 99 108\n",
1542+
MakeInstruction(spv::Op::OpSpecConstantTargetINTEL,
1543+
{1, 2, 42, 99, 108})},
1544+
1545+
{"%2 = OpSpecConstantArchitectureINTEL %1 42 99 108 72\n",
1546+
MakeInstruction(spv::Op::OpSpecConstantArchitectureINTEL,
1547+
{1, 2, 42, 99, 108, 72})},
1548+
1549+
{"%2 = OpSpecConstantCapabilitiesINTEL %1\n",
1550+
MakeInstruction(spv::Op::OpSpecConstantCapabilitiesINTEL, {1, 2})},
1551+
1552+
{"%2 = OpSpecConstantCapabilitiesINTEL %1 Kernel\n",
1553+
MakeInstruction(spv::Op::OpSpecConstantCapabilitiesINTEL,
1554+
{1, 2, (uint32_t)spv::Capability::Kernel})},
1555+
1556+
{"%2 = OpSpecConstantCapabilitiesINTEL %1 Kernel Shader\n",
1557+
MakeInstruction(spv::Op::OpSpecConstantCapabilitiesINTEL,
1558+
{1, 2, (uint32_t)spv::Capability::Kernel,
1559+
(uint32_t)spv::Capability::Shader})},
1560+
1561+
{"%2 = OpConditionalCopyObjectINTEL %1 %3 %4\n",
1562+
MakeInstruction(spv::Op::OpConditionalCopyObjectINTEL,
1563+
{1, 2, 3, 4})},
1564+
1565+
{"%2 = OpConditionalCopyObjectINTEL %1 %3 %4 %5 %6\n",
1566+
MakeInstruction(spv::Op::OpConditionalCopyObjectINTEL,
1567+
{1, 2, 3, 4, 5, 6})},
1568+
1569+
})));
1570+
14981571
} // namespace
14991572
} // namespace spvtools

utils/ggt.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ def __init__(self, extensions: List[str], operand_kinds:List[dict], printing_cla
242242
'MatrixMultiplyAccumulateOperands',
243243
'RawAccessChainOperands',
244244
'FPEncoding',
245-
'TensorOperands']
245+
'TensorOperands',
246+
'Capability']
246247

247248
def dump(self) -> None:
248249
self.context.dump()

0 commit comments

Comments
 (0)