1 # --- T2-COPYRIGHT-BEGIN ---
2 # t2/package/*/spirv-tools/hotfix-opcodes.patch
3 # Copyright (C) 2025 The T2 SDE Project
4 # SPDX-License-Identifier: GPL-2.0 or patched project license
5 # --- T2-COPYRIGHT-END ---
7 Removed all mentions to Nvidia specific opcodes as this does not build with standard spirv-headers
8 and requires some extensions to be enabled.
9 This should have been put behing a config flag and not assumed to be available by default.
11 - NoTag <notag@t2sde.org>
13 --- SPIRV-Tools-2024.4.rc2/source/operand.cpp.vanilla 2025-01-25 22:15:28.853564506 +0100
14 +++ SPIRV-Tools-2024.4.rc2/source/operand.cpp 2025-01-25 22:51:13.914202904 +0100
16 case spv::Op::OpTypeArray:
17 out = [](unsigned index) { return index == 1; };
19 - case spv::Op::OpCooperativeMatrixPerElementOpNV:
20 - out = [](unsigned index) { return index == 3; };
22 - case spv::Op::OpCooperativeMatrixReduceNV:
23 - out = [](unsigned index) { return index == 4; };
25 - case spv::Op::OpCooperativeMatrixLoadTensorNV:
26 - // approximate, due to variable operands
27 - out = [](unsigned index) { return index > 6; };
30 out = [](unsigned) { return false; };
32 --- SPIRV-Tools-2024.4.rc2/source/opcode.cpp.vanilla 2025-01-25 22:30:14.362918172 +0100
33 +++ SPIRV-Tools-2024.4.rc2/source/opcode.cpp 2025-01-25 22:49:40.816209955 +0100
35 case spv::Op::OpTypeRayQueryKHR:
36 case spv::Op::OpTypeHitObjectNV:
37 case spv::Op::OpTypeUntypedPointerKHR:
38 - case spv::Op::OpTypeTensorLayoutNV:
39 - case spv::Op::OpTypeTensorViewNV:
42 // In particular, OpTypeForwardPointer does not generate a type,
43 --- SPIRV-Tools-2024.4.rc2/source/val/validate_arithmetics.cpp.vanilla 2025-01-25 22:54:19.586848025 +0100
44 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_arithmetics.cpp 2025-01-25 22:55:02.970799346 +0100
49 - case spv::Op::OpCooperativeMatrixReduceNV: {
50 - if (!_.IsCooperativeMatrixKHRType(result_type)) {
51 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
52 - << "Result Type must be a cooperative matrix type: "
53 - << spvOpcodeString(opcode);
56 - const auto result_comp_type_id =
57 - _.FindDef(result_type)->GetOperandAs<uint32_t>(1);
59 - const auto matrix_id = inst->GetOperandAs<uint32_t>(2);
60 - const auto matrix = _.FindDef(matrix_id);
61 - const auto matrix_type_id = matrix->type_id();
62 - if (!_.IsCooperativeMatrixKHRType(matrix_type_id)) {
63 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
64 - << "Matrix must have a cooperative matrix type: "
65 - << spvOpcodeString(opcode);
67 - const auto matrix_type = _.FindDef(matrix_type_id);
68 - const auto matrix_comp_type_id = matrix_type->GetOperandAs<uint32_t>(1);
69 - if (matrix_comp_type_id != result_comp_type_id) {
70 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
71 - << "Result Type and Matrix type must have the same component "
73 - << spvOpcodeString(opcode);
75 - if (_.FindDef(result_type)->GetOperandAs<uint32_t>(2) !=
76 - matrix_type->GetOperandAs<uint32_t>(2)) {
77 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
78 - << "Result Type and Matrix type must have the same scope: "
79 - << spvOpcodeString(opcode);
82 - if (!_.IsCooperativeMatrixAccType(result_type)) {
83 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
84 - << "Result Type must have UseAccumulator: "
85 - << spvOpcodeString(opcode);
87 - if (!_.IsCooperativeMatrixAccType(matrix_type_id)) {
88 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
89 - << "Matrix type must have UseAccumulator: "
90 - << spvOpcodeString(opcode);
93 - const auto reduce_value = inst->GetOperandAs<uint32_t>(3);
97 - spv::CooperativeMatrixReduceMask::CooperativeMatrixReduce2x2)) &&
98 - (reduce_value & uint32_t(spv::CooperativeMatrixReduceMask::Row |
99 - spv::CooperativeMatrixReduceMask::Column))) {
100 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
101 - << "Reduce 2x2 must not be used with Row/Column: "
102 - << spvOpcodeString(opcode);
105 - std::tuple<bool, bool, uint32_t> result_rows, result_cols, matrix_rows,
108 - _.EvalInt32IfConst(_.FindDef(result_type)->GetOperandAs<uint32_t>(3));
110 - _.EvalInt32IfConst(_.FindDef(result_type)->GetOperandAs<uint32_t>(4));
111 - matrix_rows = _.EvalInt32IfConst(matrix_type->GetOperandAs<uint32_t>(3));
112 - matrix_cols = _.EvalInt32IfConst(matrix_type->GetOperandAs<uint32_t>(4));
116 - spv::CooperativeMatrixReduceMask::CooperativeMatrixReduce2x2)) {
117 - if (std::get<1>(result_rows) && std::get<1>(result_cols) &&
118 - std::get<1>(matrix_rows) && std::get<1>(matrix_cols) &&
119 - (std::get<2>(result_rows) != std::get<2>(matrix_rows) / 2 ||
120 - std::get<2>(result_cols) != std::get<2>(matrix_cols) / 2)) {
121 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
122 - << "For Reduce2x2, result rows/cols must be half of matrix "
124 - << spvOpcodeString(opcode);
127 - if (reduce_value == uint32_t(spv::CooperativeMatrixReduceMask::Row)) {
128 - if (std::get<1>(result_rows) && std::get<1>(matrix_rows) &&
129 - std::get<2>(result_rows) != std::get<2>(matrix_rows)) {
130 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
131 - << "For ReduceRow, result rows must match matrix rows: "
132 - << spvOpcodeString(opcode);
135 - if (reduce_value == uint32_t(spv::CooperativeMatrixReduceMask::Column)) {
136 - if (std::get<1>(result_cols) && std::get<1>(matrix_cols) &&
137 - std::get<2>(result_cols) != std::get<2>(matrix_cols)) {
138 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
139 - << "For ReduceColumn, result cols must match matrix cols: "
140 - << spvOpcodeString(opcode);
144 - const auto combine_func_id = inst->GetOperandAs<uint32_t>(4);
145 - const auto combine_func = _.FindDef(combine_func_id);
146 - if (!combine_func || combine_func->opcode() != spv::Op::OpFunction) {
147 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
148 - << "CombineFunc must be a function: " << spvOpcodeString(opcode);
150 - const auto function_type_id = combine_func->GetOperandAs<uint32_t>(3);
151 - const auto function_type = _.FindDef(function_type_id);
152 - if (function_type->operands().size() != 4) {
153 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
154 - << "CombineFunc must have two parameters: "
155 - << spvOpcodeString(opcode);
157 - for (uint32_t i = 0; i < 3; ++i) {
158 - // checks return type and two params
159 - const auto param_type_id = function_type->GetOperandAs<uint32_t>(i + 1);
160 - if (param_type_id != matrix_comp_type_id) {
161 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
162 - << "CombineFunc return type and parameters must match matrix "
164 - << spvOpcodeString(opcode);
174 --- SPIRV-Tools-2024.4.rc2/source/val/validate_conversion.cpp.vanilla 2025-01-25 22:57:18.002722741 +0100
175 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_conversion.cpp 2025-01-25 22:57:34.592959001 +0100
180 - case spv::Op::OpCooperativeMatrixConvertNV:
181 - case spv::Op::OpCooperativeMatrixTransposeNV: {
182 - if (!_.IsCooperativeMatrixType(result_type)) {
183 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
184 - << "Expected cooperative matrix Result Type: "
185 - << spvOpcodeString(opcode);
187 - const uint32_t input_type = _.GetOperandTypeId(inst, 2);
188 - if (!_.IsCooperativeMatrixType(input_type)) {
189 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
190 - << "Expected cooperative matrix type for Matrix input: "
191 - << spvOpcodeString(opcode);
194 - bool swap_row_col = (opcode == spv::Op::OpCooperativeMatrixTransposeNV);
195 - if (auto error = _.CooperativeMatrixShapesMatch(
196 - inst, result_type, input_type, true, swap_row_col))
199 - if (opcode == spv::Op::OpCooperativeMatrixConvertNV) {
200 - if (_.FindDef(result_type)->GetOperandAs<uint32_t>(1) !=
201 - _.FindDef(input_type)->GetOperandAs<uint32_t>(1)) {
202 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
203 - << "Result Type and Matrix component types mismatch: "
204 - << spvOpcodeString(opcode);
208 - if (opcode == spv::Op::OpCooperativeMatrixTransposeNV) {
209 - if (!_.IsCooperativeMatrixBType(result_type)) {
210 - return _.diag(SPV_ERROR_INVALID_DATA, inst)
211 - << "Result Type must have UseB: " << spvOpcodeString(opcode);
220 --- SPIRV-Tools-2024.4.rc2/source/val/validate_function.cpp.vanilla 2025-01-25 23:05:10.552786671 +0100
221 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_function.cpp 2025-01-25 23:05:45.296614810 +0100
223 spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple,
224 spv::Op::OpGetKernelLocalSizeForSubgroupCount,
225 spv::Op::OpGetKernelMaxNumSubgroups,
227 - spv::Op::OpCooperativeMatrixPerElementOpNV,
228 - spv::Op::OpCooperativeMatrixReduceNV,
229 - spv::Op::OpCooperativeMatrixLoadTensorNV};
231 for (auto& pair : inst->uses()) {
232 const auto* use = pair.first;
233 if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) ==
234 --- SPIRV-Tools-2024.4.rc2/source/val/validate_function.cpp.vanilla 2025-01-25 23:06:47.837505542 +0100
235 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_function.cpp 2025-01-25 23:07:29.951438753 +0100
237 case spv::Op::OpFunctionCall:
238 if (auto error = ValidateFunctionCall(_, inst)) return error;
240 - case spv::Op::OpCooperativeMatrixPerElementOpNV:
241 - if (auto error = ValidateCooperativeMatrixPerElementOp(_, inst))
247 --- SPIRV-Tools-2024.4.rc2/source/val/validate_memory.cpp.vanilla 2025-01-25 23:09:49.430091847 +0100
248 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_memory.cpp 2025-01-25 23:12:42.792561005 +0100
249 @@ -232,18 +232,12 @@
250 spv::StorageClass dst_sc = spv::StorageClass::Max;
251 spv::StorageClass src_sc = spv::StorageClass::Max;
252 switch (inst->opcode()) {
253 - case spv::Op::OpCooperativeMatrixLoadNV:
254 - case spv::Op::OpCooperativeMatrixLoadTensorNV:
255 - case spv::Op::OpCooperativeMatrixLoadKHR:
256 case spv::Op::OpLoad: {
257 auto load_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(2));
258 auto load_pointer_type = _.FindDef(load_pointer->type_id());
259 dst_sc = load_pointer_type->GetOperandAs<spv::StorageClass>(1);
262 - case spv::Op::OpCooperativeMatrixStoreNV:
263 - case spv::Op::OpCooperativeMatrixStoreTensorNV:
264 - case spv::Op::OpCooperativeMatrixStoreKHR:
265 case spv::Op::OpStore: {
266 auto store_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(0));
267 auto store_pointer_type = _.FindDef(store_pointer->type_id());
269 const uint32_t mask = inst->GetOperandAs<uint32_t>(index);
270 if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) {
271 if (inst->opcode() == spv::Op::OpLoad ||
272 - inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV ||
273 - inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV ||
274 inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
275 return _.diag(SPV_ERROR_INVALID_ID, inst)
276 << "MakePointerAvailableKHR cannot be used with OpLoad.";
277 @@ -2180,222 +2172,6 @@
283 -// Returns the number of instruction words taken up by a tensor addressing
284 -// operands argument and its implied operands.
285 -int TensorAddressingOperandsNumWords(spv::TensorAddressingOperandsMask mask) {
286 - int result = 1; // Count the mask
287 - if ((mask & spv::TensorAddressingOperandsMask::TensorView) !=
288 - spv::TensorAddressingOperandsMask::MaskNone)
290 - if ((mask & spv::TensorAddressingOperandsMask::DecodeFunc) !=
291 - spv::TensorAddressingOperandsMask::MaskNone)
296 -spv_result_t ValidateCooperativeMatrixLoadStoreTensorNV(
297 - ValidationState_t& _, const Instruction* inst) {
299 - const char* opname;
300 - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
301 - type_id = inst->type_id();
302 - opname = "spv::Op::OpCooperativeMatrixLoadTensorNV";
304 - // get Object operand's type
305 - type_id = _.FindDef(inst->GetOperandAs<uint32_t>(1))->type_id();
306 - opname = "spv::Op::OpCooperativeMatrixStoreTensorNV";
309 - auto matrix_type = _.FindDef(type_id);
311 - if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) {
312 - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
313 - return _.diag(SPV_ERROR_INVALID_ID, inst)
314 - << "spv::Op::OpCooperativeMatrixLoadTensorNV Result Type <id> "
315 - << _.getIdName(type_id) << " is not a cooperative matrix type.";
317 - return _.diag(SPV_ERROR_INVALID_ID, inst)
318 - << "spv::Op::OpCooperativeMatrixStoreTensorNV Object type <id> "
319 - << _.getIdName(type_id) << " is not a cooperative matrix type.";
323 - const auto pointer_index =
324 - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 2u : 0u;
325 - const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
326 - const auto pointer = _.FindDef(pointer_id);
328 - ((_.addressing_model() == spv::AddressingModel::Logical) &&
329 - ((!_.features().variable_pointers &&
330 - !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
331 - (_.features().variable_pointers &&
332 - !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
333 - return _.diag(SPV_ERROR_INVALID_ID, inst)
334 - << opname << " Pointer <id> " << _.getIdName(pointer_id)
335 - << " is not a logical pointer.";
338 - const auto pointer_type_id = pointer->type_id();
339 - const auto pointer_type = _.FindDef(pointer_type_id);
340 - if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
341 - return _.diag(SPV_ERROR_INVALID_ID, inst)
342 - << opname << " type for pointer <id> " << _.getIdName(pointer_id)
343 - << " is not a pointer type.";
346 - const auto storage_class_index = 1u;
347 - const auto storage_class =
348 - pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);
350 - if (storage_class != spv::StorageClass::Workgroup &&
351 - storage_class != spv::StorageClass::StorageBuffer &&
352 - storage_class != spv::StorageClass::PhysicalStorageBuffer) {
353 - return _.diag(SPV_ERROR_INVALID_ID, inst)
354 - << _.VkErrorID(8973) << opname
355 - << " storage class for pointer type <id> "
356 - << _.getIdName(pointer_type_id)
357 - << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer.";
360 - if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
361 - const auto object_index = 3;
362 - const auto object_id = inst->GetOperandAs<uint32_t>(object_index);
363 - const auto object = _.FindDef(object_id);
364 - if (!object || object->type_id() != type_id) {
365 - return _.diag(SPV_ERROR_INVALID_ID, inst)
366 - << opname << " Object <id> " << _.getIdName(object_id)
367 - << " type does not match Result Type.";
371 - const auto tensor_layout_index =
372 - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 4u : 2u;
373 - const auto tensor_layout_id =
374 - inst->GetOperandAs<uint32_t>(tensor_layout_index);
375 - const auto tensor_layout = _.FindDef(tensor_layout_id);
376 - if (!tensor_layout || _.FindDef(tensor_layout->type_id())->opcode() !=
377 - spv::Op::OpTypeTensorLayoutNV) {
378 - return _.diag(SPV_ERROR_INVALID_ID, inst)
379 - << opname << " TensorLayout <id> " << _.getIdName(tensor_layout_id)
380 - << " does not have a tensor layout type.";
383 - const auto memory_access_index =
384 - (inst->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) ? 5u : 3u;
385 - if (inst->operands().size() > memory_access_index) {
386 - if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
390 - const auto memory_access_mask =
391 - inst->GetOperandAs<uint32_t>(memory_access_index);
392 - const auto tensor_operands_index =
393 - memory_access_index + MemoryAccessNumWords(memory_access_mask);
394 - const auto tensor_operands =
395 - inst->GetOperandAs<spv::TensorAddressingOperandsMask>(
396 - tensor_operands_index);
398 - if (inst->operands().size() <
399 - tensor_operands_index +
400 - TensorAddressingOperandsNumWords(tensor_operands)) {
401 - return _.diag(SPV_ERROR_INVALID_ID, inst)
402 - << opname << " not enough tensor addressing operands.";
405 - uint32_t tensor_operand_index = tensor_operands_index + 1;
406 - if ((tensor_operands & spv::TensorAddressingOperandsMask::TensorView) !=
407 - spv::TensorAddressingOperandsMask::MaskNone) {
408 - const auto tensor_view_id =
409 - inst->GetOperandAs<uint32_t>(tensor_operand_index);
410 - const auto tensor_view = _.FindDef(tensor_view_id);
411 - if (!tensor_view || _.FindDef(tensor_view->type_id())->opcode() !=
412 - spv::Op::OpTypeTensorViewNV) {
413 - return _.diag(SPV_ERROR_INVALID_ID, inst)
414 - << opname << " TensorView <id> " << _.getIdName(tensor_view_id)
415 - << " does not have a tensor view type.";
418 - tensor_operand_index++;
421 - if ((tensor_operands & spv::TensorAddressingOperandsMask::DecodeFunc) !=
422 - spv::TensorAddressingOperandsMask::MaskNone) {
423 - if (inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV) {
424 - return _.diag(SPV_ERROR_INVALID_ID, inst)
425 - << "OpCooperativeMatrixStoreTensorNV does not support DecodeFunc.";
427 - const auto decode_func_id =
428 - inst->GetOperandAs<uint32_t>(tensor_operand_index);
429 - const auto decode_func = _.FindDef(decode_func_id);
431 - if (!decode_func || decode_func->opcode() != spv::Op::OpFunction) {
432 - return _.diag(SPV_ERROR_INVALID_ID, inst)
433 - << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
434 - << " is not a function.";
437 - const auto component_type_index = 1;
438 - const auto component_type_id =
439 - matrix_type->GetOperandAs<uint32_t>(component_type_index);
441 - const auto function_type =
442 - _.FindDef(decode_func->GetOperandAs<uint32_t>(3));
443 - if (function_type->GetOperandAs<uint32_t>(1) != component_type_id) {
444 - return _.diag(SPV_ERROR_INVALID_ID, inst)
445 - << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
446 - << " return type must match matrix component type.";
449 - const auto decode_ptr_type_id = function_type->GetOperandAs<uint32_t>(2);
450 - const auto decode_ptr_type = _.FindDef(decode_ptr_type_id);
451 - auto decode_storage_class =
452 - decode_ptr_type->GetOperandAs<spv::StorageClass>(storage_class_index);
454 - if (decode_storage_class != spv::StorageClass::PhysicalStorageBuffer) {
455 - return _.diag(SPV_ERROR_INVALID_ID, inst)
456 - << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
457 - << " first parameter must be pointer to PhysicalStorageBuffer.";
460 - const auto tensor_layout_type = _.FindDef(tensor_layout->type_id());
462 - for (uint32_t param = 3; param < 5; ++param) {
463 - const auto param_type_id = function_type->GetOperandAs<uint32_t>(param);
464 - const auto param_type = _.FindDef(param_type_id);
465 - if (param_type->opcode() != spv::Op::OpTypeArray) {
466 - return _.diag(SPV_ERROR_INVALID_ID, inst)
467 - << opname << " DecodeFunc <id> " << _.getIdName(decode_func_id)
468 - << " second/third parameter must be array of 32-bit integer "
470 - << " dimension equal to the tensor dimension.";
472 - const auto length_index = 2u;
473 - uint64_t array_length;
474 - if (_.EvalConstantValUint64(
475 - param_type->GetOperandAs<uint32_t>(length_index),
477 - const auto tensor_layout_dim_id =
478 - tensor_layout_type->GetOperandAs<uint32_t>(1);
479 - uint64_t dim_value;
480 - if (_.EvalConstantValUint64(tensor_layout_dim_id, &dim_value)) {
481 - if (array_length != dim_value) {
482 - return _.diag(SPV_ERROR_INVALID_ID, inst)
483 - << opname << " DecodeFunc <id> "
484 - << _.getIdName(decode_func_id)
485 - << " second/third parameter must be array of 32-bit integer "
487 - << " dimension equal to the tensor dimension.";
493 - tensor_operand_index++;
496 - return SPV_SUCCESS;
499 spv_result_t ValidatePtrComparison(ValidationState_t& _,
500 --- SPIRV-Tools-2024.4.rc2/source/val/validate_memory.cpp.vanilla 2025-01-25 23:15:04.657914825 +0100
501 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_memory.cpp 2025-01-25 23:17:00.042891392 +0100
504 if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) {
505 if (inst->opcode() == spv::Op::OpStore ||
506 - inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV ||
507 - inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR ||
508 - inst->opcode() == spv::Op::OpCooperativeMatrixStoreTensorNV) {
509 + inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR) {
510 return _.diag(SPV_ERROR_INVALID_ID, inst)
511 << "MakePointerVisibleKHR cannot be used with OpStore.";
513 @@ -2282,11 +2280,6 @@
514 if (auto error = ValidateCooperativeMatrixLoadStoreKHR(_, inst))
517 - case spv::Op::OpCooperativeMatrixLoadTensorNV:
518 - case spv::Op::OpCooperativeMatrixStoreTensorNV:
519 - if (auto error = ValidateCooperativeMatrixLoadStoreTensorNV(_, inst))
522 case spv::Op::OpPtrEqual:
523 case spv::Op::OpPtrNotEqual:
524 case spv::Op::OpPtrDiff:
525 --- SPIRV-Tools-2024.4.rc2/source/CMakeLists.txt.vanilla 2025-01-25 23:20:28.855865030 +0100
526 +++ SPIRV-Tools-2024.4.rc2/source/CMakeLists.txt 2025-01-25 23:20:34.232608244 +0100
528 ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_ray_tracing_reorder.cpp
529 ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_scopes.cpp
530 ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_small_type_uses.cpp
531 - ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_tensor_layout.cpp
532 ${CMAKE_CURRENT_SOURCE_DIR}/val/validate_type.cpp
533 ${CMAKE_CURRENT_SOURCE_DIR}/val/decoration.h
534 ${CMAKE_CURRENT_SOURCE_DIR}/val/basic_block.cpp
535 --- SPIRV-Tools-2024.4.rc2/source/val/validate_type.cpp.vanilla 2025-01-25 23:21:36.256824767 +0100
536 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_type.cpp 2025-01-25 23:23:51.545418070 +0100
542 -spv_result_t ValidateTypeTensorLayoutNV(ValidationState_t& _,
543 - const Instruction* inst) {
544 - if (auto error = ValidateTensorDim(_, inst)) return error;
546 - const auto clamp_index = 2;
547 - const auto clamp_id = inst->GetOperandAs<uint32_t>(clamp_index);
548 - const auto clamp = _.FindDef(clamp_id);
549 - if (!clamp || !_.IsIntScalarType(clamp->type_id()) ||
550 - _.GetBitWidth(clamp->type_id()) != 32) {
551 - return _.diag(SPV_ERROR_INVALID_ID, inst)
552 - << spvOpcodeString(inst->opcode()) << " ClampMode <id> "
553 - << _.getIdName(clamp_id) << " is not a 32-bit integer.";
556 - uint64_t clamp_value;
557 - if (_.EvalConstantValUint64(clamp_id, &clamp_value)) {
559 - static_cast<uint32_t>(spv::TensorClampMode::RepeatMirrored)) {
560 - return _.diag(SPV_ERROR_INVALID_ID, inst)
561 - << spvOpcodeString(inst->opcode()) << " ClampMode <id> "
562 - << _.getIdName(clamp_id) << " must be a valid TensorClampMode.";
566 - return SPV_SUCCESS;
569 -spv_result_t ValidateTypeTensorViewNV(ValidationState_t& _,
570 - const Instruction* inst) {
571 - if (auto error = ValidateTensorDim(_, inst)) return error;
573 - const auto has_dim_index = 2;
574 - const auto has_dim_id = inst->GetOperandAs<uint32_t>(has_dim_index);
575 - const auto has_dim = _.FindDef(has_dim_id);
576 - if (!has_dim || !_.IsBoolScalarType(has_dim->type_id())) {
577 - return _.diag(SPV_ERROR_INVALID_ID, inst)
578 - << spvOpcodeString(inst->opcode()) << " HasDimensions <id> "
579 - << _.getIdName(has_dim_id) << " is not a boolean value.";
582 - uint32_t permutation_mask = 0;
583 - bool all_constant = true;
584 - const auto num_dim = inst->operands().size() - 3;
585 - for (size_t p_index = 3; p_index < inst->operands().size(); ++p_index) {
586 - auto p_id = inst->GetOperandAs<uint32_t>(p_index);
587 - const auto p = _.FindDef(p_id);
588 - if (!p || !_.IsIntScalarType(p->type_id()) ||
589 - _.GetBitWidth(p->type_id()) != 32) {
590 - return _.diag(SPV_ERROR_INVALID_ID, inst)
591 - << spvOpcodeString(inst->opcode()) << " Permutation <id> "
592 - << _.getIdName(p_id) << " is not a 32-bit integer.";
596 - if (_.EvalConstantValUint64(p_id, &p_value)) {
597 - if (p_value >= num_dim) {
598 - return _.diag(SPV_ERROR_INVALID_ID, inst)
599 - << spvOpcodeString(inst->opcode()) << " Permutation <id> "
600 - << _.getIdName(p_id) << " must be a valid dimension.";
602 - permutation_mask |= 1 << p_value;
604 - all_constant = false;
607 - if (all_constant && permutation_mask != (1U << num_dim) - 1U) {
608 - return _.diag(SPV_ERROR_INVALID_ID, inst)
609 - << spvOpcodeString(inst->opcode())
610 - << " Permutation values don't form a valid permutation.";
613 - uint64_t dim_value;
614 - if (_.EvalConstantValUint64(inst->GetOperandAs<uint32_t>(1), &dim_value)) {
615 - if (dim_value != num_dim) {
616 - return _.diag(SPV_ERROR_INVALID_ID, inst)
617 - << spvOpcodeString(inst->opcode())
618 - << " Incorrect number of permutation values.";
622 - return SPV_SUCCESS;
626 spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) {
627 --- SPIRV-Tools-2024.4.rc2/source/val/validate_type.cpp.vanilla 2025-01-26 00:19:12.266430789 +0100
628 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_type.cpp 2025-01-26 00:19:26.186628346 +0100
629 @@ -710,19 +710,12 @@
630 case spv::Op::OpTypeForwardPointer:
631 if (auto error = ValidateTypeForwardPointer(_, inst)) return error;
633 - case spv::Op::OpTypeCooperativeMatrixNV:
634 case spv::Op::OpTypeCooperativeMatrixKHR:
635 if (auto error = ValidateTypeCooperativeMatrix(_, inst)) return error;
637 case spv::Op::OpTypeUntypedPointerKHR:
638 if (auto error = ValidateTypeUntypedPointerKHR(_, inst)) return error;
640 - case spv::Op::OpTypeTensorLayoutNV:
641 - if (auto error = ValidateTypeTensorLayoutNV(_, inst)) return error;
643 - case spv::Op::OpTypeTensorViewNV:
644 - if (auto error = ValidateTypeTensorViewNV(_, inst)) return error;
649 --- SPIRV-Tools-2024.4.rc2/source/opt/aggressive_dead_code_elim_pass.cpp.vanilla 2025-01-26 00:22:25.859178640 +0100
650 +++ SPIRV-Tools-2024.4.rc2/source/opt/aggressive_dead_code_elim_pass.cpp 2025-01-26 00:22:40.569387428 +0100
655 - case spv::Op::OpCooperativeMatrixLoadNV:
656 case spv::Op::OpCooperativeMatrixLoadKHR:
657 - case spv::Op::OpCooperativeMatrixLoadTensorNV:
658 return GetVariableId(
659 inst->GetSingleWordInOperand(kCooperativeMatrixLoadSourceAddrInIdx));
661 --- SPIRV-Tools-2024.4.rc2/source/opt/ir_context.cpp.vanilla 2025-01-26 00:23:25.530025612 +0100
662 +++ SPIRV-Tools-2024.4.rc2/source/opt/ir_context.cpp 2025-01-26 00:23:49.107026952 +0100
664 for (auto ii = bi->begin(); ii != bi->end(); ++ii) {
665 if (ii->opcode() == spv::Op::OpFunctionCall)
666 todo->push(ii->GetSingleWordInOperand(0));
667 - if (ii->opcode() == spv::Op::OpCooperativeMatrixPerElementOpNV)
668 - todo->push(ii->GetSingleWordInOperand(1));
669 - if (ii->opcode() == spv::Op::OpCooperativeMatrixReduceNV)
670 - todo->push(ii->GetSingleWordInOperand(2));
671 - if (ii->opcode() == spv::Op::OpCooperativeMatrixLoadTensorNV) {
672 - const auto memory_operands_index = 3;
673 - auto mask = ii->GetSingleWordInOperand(memory_operands_index);
675 - uint32_t count = 1;
676 - if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) ++count;
677 - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR))
679 - if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR))
682 - const auto tensor_operands_index = memory_operands_index + count;
683 - mask = ii->GetSingleWordInOperand(tensor_operands_index);
685 - if (mask & uint32_t(spv::TensorAddressingOperandsMask::TensorView))
688 - if (mask & uint32_t(spv::TensorAddressingOperandsMask::DecodeFunc)) {
689 - todo->push(ii->GetSingleWordInOperand(tensor_operands_index + count));
695 --- SPIRV-Tools-2024.4.rc2/source/val/validation_state.cpp.vanilla 2025-01-26 00:21:36.611813063 +0100
696 +++ SPIRV-Tools-2024.4.rc2/source/val/validation_state.cpp 2025-01-26 00:21:41.138543966 +0100
697 @@ -1360,7 +1360,6 @@
698 if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value &&
699 // CooperativeMatrixConversionsNV allows conversions from Acc->A/B
701 - HasCapability(spv::Capability::CooperativeMatrixConversionsNV) &&
703 (uint32_t)spv::CooperativeMatrixUse::MatrixAccumulatorKHR)) {
704 return diag(SPV_ERROR_INVALID_DATA, inst)
705 --- SPIRV-Tools-2024.4.rc2/source/val/validate.cpp.vanilla 2025-01-26 00:25:42.315300671 +0100
706 +++ SPIRV-Tools-2024.4.rc2/source/val/validate.cpp 2025-01-26 00:25:50.085410973 +0100
708 if (auto error = RayTracingPass(*vstate, &instruction)) return error;
709 if (auto error = RayReorderNVPass(*vstate, &instruction)) return error;
710 if (auto error = MeshShadingPass(*vstate, &instruction)) return error;
711 - if (auto error = TensorLayoutPass(*vstate, &instruction)) return error;
714 // Validate the preconditions involving adjacent instructions. e.g.
715 --- SPIRV-Tools-2024.4.rc2/source/val/validate.h.vanilla 2025-01-26 00:25:57.508849664 +0100
716 +++ SPIRV-Tools-2024.4.rc2/source/val/validate.h 2025-01-26 00:26:03.648936827 +0100
718 /// Calculates the reachability of basic blocks.
719 void ReachabilityPass(ValidationState_t& _);
721 -/// Validates tensor layout and view instructions.
722 -spv_result_t TensorLayoutPass(ValidationState_t& _, const Instruction* inst);
724 /// Validates execution limitations.
726 /// Verifies execution models are allowed for all functionality they contain.
727 --- SPIRV-Tools-2024.4.rc2/source/val/validate_tensor_layout.cpp.vanilla 2025-01-26 00:26:11.169043564 +0100
728 +++ SPIRV-Tools-2024.4.rc2/source/val/validate_tensor_layout.cpp 2025-01-26 00:26:33.239356847 +0100
733 -spv_result_t TensorLayoutPass(ValidationState_t& _, const Instruction* inst) {
734 - switch (inst->opcode()) {
735 - case spv::Op::OpCreateTensorLayoutNV:
736 - if (auto error = ValidateCreateTensorLayoutNV(_, inst)) return error;
738 - case spv::Op::OpCreateTensorViewNV:
739 - if (auto error = ValidateCreateTensorViewNV(_, inst)) return error;
741 - case spv::Op::OpTensorLayoutSetBlockSizeNV:
742 - case spv::Op::OpTensorLayoutSetDimensionNV:
743 - case spv::Op::OpTensorLayoutSetStrideNV:
744 - if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, DIM, false))
747 - case spv::Op::OpTensorLayoutSliceNV:
748 - if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, DIMx2, false))
751 - case spv::Op::OpTensorLayoutSetClampValueNV:
752 - if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, ONE, false))
755 - case spv::Op::OpTensorViewSetDimensionNV:
756 - case spv::Op::OpTensorViewSetStrideNV:
757 - if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, DIM, true))
760 - case spv::Op::OpTensorViewSetClipNV:
761 - if (auto error = ValidateTensorTypeWithDimValuesNV(_, inst, FOUR, true))
768 - return SPV_SUCCESS;
772 } // namespace spvtools
773 --- SPIRV-Tools-2024.4.rc2/source/opt/type_manager.cpp.vanilla 2025-01-26 00:27:52.257145391 +0100
774 +++ SPIRV-Tools-2024.4.rc2/source/opt/type_manager.cpp 2025-01-26 00:28:06.254010827 +0100
776 {SPV_OPERAND_TYPE_ID, {coop_mat->use_id()}}});
779 - case Type::kTensorLayoutNV: {
780 - auto tensor_layout = type->AsTensorLayoutNV();
781 - typeInst = MakeUnique<Instruction>(
782 - context(), spv::Op::OpTypeTensorLayoutNV, 0, id,
783 - std::initializer_list<Operand>{
784 - {SPV_OPERAND_TYPE_ID, {tensor_layout->dim_id()}},
785 - {SPV_OPERAND_TYPE_ID, {tensor_layout->clamp_mode_id()}}});
788 - case Type::kTensorViewNV: {
789 - auto tensor_view = type->AsTensorViewNV();
790 - std::vector<Operand> operands;
791 - operands.push_back(Operand{SPV_OPERAND_TYPE_ID, {tensor_view->dim_id()}});
792 - operands.push_back(
793 - Operand{SPV_OPERAND_TYPE_ID, {tensor_view->has_dimensions_id()}});
794 - for (auto p : tensor_view->perm()) {
795 - operands.push_back(Operand{SPV_OPERAND_TYPE_ID, {p}});
797 - typeInst = MakeUnique<Instruction>(context(), spv::Op::OpTypeTensorViewNV,
802 assert(false && "Unexpected type");
804 --- SPIRV-Tools-2024.4.rc2/source/opt/type_manager.cpp.vanilla 2025-01-26 00:34:46.216356362 +0100
805 +++ SPIRV-Tools-2024.4.rc2/source/opt/type_manager.cpp 2025-01-26 00:34:56.533169548 +0100
807 case spv::Op::OpTypeRayQueryKHR:
808 type = new RayQueryKHR();
810 - case spv::Op::OpTypeHitObjectNV:
811 - type = new HitObjectNV();
813 - case spv::Op::OpTypeTensorLayoutNV:
814 - type = new TensorLayoutNV(inst.GetSingleWordInOperand(0),
815 - inst.GetSingleWordInOperand(1));
817 - case spv::Op::OpTypeTensorViewNV: {
818 - const auto count = inst.NumOperands();
819 - std::vector<uint32_t> perm;
820 - for (uint32_t i = 2; i < count; ++i) {
821 - perm.push_back(inst.GetSingleWordOperand(i));
823 - type = new TensorViewNV(inst.GetSingleWordInOperand(0),
824 - inst.GetSingleWordInOperand(1), perm);
828 assert(false && "Type not handled by the type manager.");