Coverage Report

Created: 2026-02-14 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spirv-tools/source/operand.cpp
Line
Count
Source
1
// Copyright (c) 2015-2020 The Khronos Group Inc.
2
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
3
// reserved.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
//     http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
17
#include "source/operand.h"
18
19
#include <assert.h>
20
#include <string.h>
21
22
#include <algorithm>
23
24
#include "DebugInfo.h"
25
#include "OpenCLDebugInfo100.h"
26
#include "source/macro.h"
27
#include "source/opcode.h"
28
#include "source/spirv_constant.h"
29
#include "source/table2.h"
30
#include "spirv-tools/libspirv.h"
31
32
206k
const char* spvOperandTypeStr(spv_operand_type_t type) {
33
206k
  switch (type) {
34
38.5k
    case SPV_OPERAND_TYPE_ID:
35
51.8k
    case SPV_OPERAND_TYPE_OPTIONAL_ID:
36
51.8k
      return "ID";
37
7.16k
    case SPV_OPERAND_TYPE_TYPE_ID:
38
7.16k
      return "type ID";
39
14.4k
    case SPV_OPERAND_TYPE_RESULT_ID:
40
14.4k
      return "result ID";
41
11.9k
    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
42
16.7k
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
43
16.7k
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
44
16.9k
    case SPV_OPERAND_TYPE_LITERAL_FLOAT:
45
16.9k
      return "literal number";
46
20.2k
    case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
47
20.2k
      return "possibly multi-word literal integer";
48
2.65k
    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
49
2.65k
      return "possibly multi-word literal number";
50
955
    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
51
955
      return "extension instruction number";
52
12.2k
    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
53
12.2k
      return "OpSpecConstantOp opcode";
54
5.54k
    case SPV_OPERAND_TYPE_LITERAL_STRING:
55
5.73k
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
56
5.73k
      return "literal string";
57
5.00k
    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
58
5.00k
      return "source language";
59
1.51k
    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
60
1.51k
      return "execution model";
61
2.13k
    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
62
2.13k
      return "addressing model";
63
1.90k
    case SPV_OPERAND_TYPE_MEMORY_MODEL:
64
1.90k
      return "memory model";
65
1.69k
    case SPV_OPERAND_TYPE_EXECUTION_MODE:
66
1.69k
      return "execution mode";
67
4.36k
    case SPV_OPERAND_TYPE_STORAGE_CLASS:
68
4.36k
      return "storage class";
69
198
    case SPV_OPERAND_TYPE_DIMENSIONALITY:
70
198
      return "dimensionality";
71
17
    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
72
17
      return "sampler addressing mode";
73
381
    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
74
381
      return "sampler filter mode";
75
383
    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
76
383
      return "image format";
77
2.26k
    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
78
2.26k
      return "floating-point fast math mode";
79
194
    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
80
194
      return "floating-point rounding mode";
81
1.12k
    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
82
1.12k
      return "linkage type";
83
772
    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
84
965
    case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
85
965
      return "access qualifier";
86
564
    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
87
564
      return "function parameter attribute";
88
9.41k
    case SPV_OPERAND_TYPE_DECORATION:
89
9.41k
      return "decoration";
90
1.50k
    case SPV_OPERAND_TYPE_BUILT_IN:
91
1.50k
      return "built-in";
92
8.93k
    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
93
8.93k
      return "selection control";
94
1.14k
    case SPV_OPERAND_TYPE_LOOP_CONTROL:
95
1.14k
      return "loop control";
96
1.15k
    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
97
1.15k
      return "function control";
98
4.90k
    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
99
4.90k
      return "memory semantics ID";
100
3.59k
    case SPV_OPERAND_TYPE_MEMORY_ACCESS:
101
3.84k
    case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
102
3.84k
      return "memory access";
103
0
    case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
104
0
      return "shading rate";
105
5.73k
    case SPV_OPERAND_TYPE_SCOPE_ID:
106
5.73k
      return "scope ID";
107
231
    case SPV_OPERAND_TYPE_GROUP_OPERATION:
108
231
      return "group operation";
109
0
    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
110
0
      return "kernel enqeue flags";
111
0
    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
112
0
      return "kernel profiling info";
113
3.01k
    case SPV_OPERAND_TYPE_CAPABILITY:
114
5.85k
    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
115
5.85k
      return "capability";
116
0
    case SPV_OPERAND_TYPE_RAY_FLAGS:
117
0
      return "ray flags";
118
0
    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
119
0
      return "ray query intersection";
120
0
    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
121
0
      return "ray query committed intersection type";
122
0
    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
123
0
      return "ray query candidate intersection type";
124
192
    case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
125
198
    case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
126
198
      return "packed vector format";
127
196
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
128
204
    case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
129
204
      return "cooperative matrix operands";
130
0
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
131
0
      return "cooperative matrix layout";
132
0
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
133
0
      return "cooperative matrix use";
134
0
    case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE:
135
0
      return "tensor clamp mode";
136
201
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
137
201
      return "cooperative matrix reduce";
138
1.31k
    case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
139
1.31k
      return "tensor addressing operands";
140
197
    case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
141
202
    case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
142
202
      return "matrix multiply accumulate operands";
143
194
    case SPV_OPERAND_TYPE_TENSOR_OPERANDS:
144
203
    case SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS:
145
203
      return "tensor operands";
146
5
    case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
147
5
      return "initialization mode qualifier";
148
195
    case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
149
195
      return "host access qualifier";
150
751
    case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
151
751
      return "load cache control";
152
380
    case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
153
380
      return "store cache control";
154
753
    case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
155
753
      return "named maximum number of registers";
156
194
    case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
157
389
    case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
158
389
      return "raw access chain operands";
159
217
    case SPV_OPERAND_TYPE_IMAGE:
160
226
    case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
161
226
      return "image";
162
0
    case SPV_OPERAND_TYPE_OPTIONAL_CIV:
163
0
      return "context-insensitive value";
164
13
    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
165
13
      return "debug info flags";
166
193
    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
167
193
      return "debug base type encoding";
168
195
    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
169
195
      return "debug composite type";
170
7
    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
171
7
      return "debug type qualifier";
172
6
    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
173
6
      return "debug operation";
174
201
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
175
201
      return "OpenCL.DebugInfo.100 debug info flags";
176
193
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
177
193
      return "OpenCL.DebugInfo.100 debug base type encoding";
178
191
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
179
191
      return "OpenCL.DebugInfo.100 debug composite type";
180
192
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
181
192
      return "OpenCL.DebugInfo.100 debug type qualifier";
182
192
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
183
192
      return "OpenCL.DebugInfo.100 debug operation";
184
2
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
185
2
      return "OpenCL.DebugInfo.100 debug imported entity";
186
757
    case SPV_OPERAND_TYPE_FPENCODING:
187
979
    case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
188
979
      return "FP encoding";
189
190
    // The next values are for values returned from an instruction, not actually
191
    // an operand.  So the specific strings don't matter.  But let's add them
192
    // for completeness and ease of testing.
193
0
    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
194
0
      return "image channel order";
195
0
    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
196
0
      return "image channel data type";
197
198
563
    case SPV_OPERAND_TYPE_FPDENORM_MODE:
199
563
      return "FP denorm mode";
200
752
    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
201
752
      return "FP operation mode";
202
0
    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
203
0
      return "quantization mode";
204
0
    case SPV_OPERAND_TYPE_OVERFLOW_MODES:
205
0
      return "overflow mode";
206
0
    case SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT:
207
0
      return "cooperative vector matrix layout";
208
0
    case SPV_OPERAND_TYPE_COMPONENT_TYPE:
209
0
      return "component type";
210
211
0
    case SPV_OPERAND_TYPE_KERNEL_PROPERTY_FLAGS:
212
0
      return "kernel property flags";
213
0
    case SPV_OPERAND_TYPE_SHDEBUG100_BUILD_IDENTIFIER_FLAGS:
214
0
      return "NonSemantic.Shader.DebugInfo.100 debug build identifier flags";
215
0
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
216
0
      return "NonSemantic.Shader.DebugInfo.100 debug base type attribute "
217
0
             "encoding";
218
0
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_COMPOSITE_TYPE:
219
0
      return "NonSemantic.Shader.DebugInfo.100 debug composite type";
220
0
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_IMPORTED_ENTITY:
221
0
      return "NonSemantic.Shader.DebugInfo.100 debug imported entity";
222
0
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_INFO_FLAGS:
223
0
      return "NonSemantic.Shader.DebugInfo.100 debug info flags";
224
0
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_OPERATION:
225
0
      return "NonSemantic.Shader.DebugInfo.100 debug operation";
226
0
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_TYPE_QUALIFIER:
227
0
      return "NonSemantic.Shader.DebugInfo.100 debug type qualifier";
228
229
0
    case SPV_OPERAND_TYPE_NONE:
230
0
      return "NONE";
231
0
    default:
232
0
      break;
233
206k
  }
234
0
  return "unknown";
235
206k
}
236
237
void spvPushOperandTypes(const spv_operand_type_t* types,
238
0
                         spv_operand_pattern_t* pattern) {
239
  // Push them on in backward order.
240
0
  const spv_operand_type_t* endTypes;
241
0
  for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
242
0
  }
243
244
0
  while (endTypes-- != types) {
245
0
    pattern->push_back(*endTypes);
246
0
  }
247
0
}
248
249
void spvPushOperandTypes(
250
    const spvtools::utils::Span<const spv_operand_type_t>& types,
251
110M
    spv_operand_pattern_t* pattern) {
252
  // Push them on in backward order.
253
110M
  auto n = types.size();
254
323M
  for (auto i = 0u; i < n; i++) {
255
213M
    auto type = types[n - 1 - i];
256
    // Check against the NONE type, in case the tables have them.
257
    // This might be cleaned up.
258
213M
    if (type != SPV_OPERAND_TYPE_NONE) {
259
213M
      pattern->push_back(type);
260
213M
    }
261
213M
  }
262
110M
}
263
264
void spvPushOperandTypesForMask(const spv_operand_type_t type,
265
                                const uint32_t mask,
266
113k
                                spv_operand_pattern_t* pattern) {
267
  // Scan from highest bits to lowest bits because we will append in LIFO
268
  // fashion, and we need the operands for lower order bits to be consumed first
269
3.75M
  for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
270
3.64M
       candidate_bit >>= 1) {
271
3.64M
    if (candidate_bit & mask) {
272
25.9k
      const spvtools::OperandDesc* entry = nullptr;
273
25.9k
      if (SPV_SUCCESS == spvtools::LookupOperand(type, candidate_bit, &entry)) {
274
25.9k
        spvPushOperandTypes(entry->operands(), pattern);
275
25.9k
      }
276
25.9k
    }
277
3.64M
  }
278
113k
}
279
280
229M
bool spvOperandIsConcrete(spv_operand_type_t type) {
281
229M
  if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
282
176M
    return true;
283
176M
  }
284
52.4M
  switch (type) {
285
21.0M
    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
286
21.3M
    case SPV_OPERAND_TYPE_LITERAL_FLOAT:
287
21.8M
    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
288
21.9M
    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
289
35.6M
    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
290
38.6M
    case SPV_OPERAND_TYPE_LITERAL_STRING:
291
38.9M
    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
292
39.4M
    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
293
40.0M
    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
294
40.6M
    case SPV_OPERAND_TYPE_MEMORY_MODEL:
295
41.0M
    case SPV_OPERAND_TYPE_EXECUTION_MODE:
296
42.8M
    case SPV_OPERAND_TYPE_STORAGE_CLASS:
297
42.8M
    case SPV_OPERAND_TYPE_DIMENSIONALITY:
298
42.8M
    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
299
42.8M
    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
300
42.9M
    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
301
42.9M
    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
302
42.9M
    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
303
43.1M
    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
304
43.3M
    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
305
43.3M
    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
306
43.6M
    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
307
49.6M
    case SPV_OPERAND_TYPE_DECORATION:
308
51.0M
    case SPV_OPERAND_TYPE_BUILT_IN:
309
51.0M
    case SPV_OPERAND_TYPE_GROUP_OPERATION:
310
51.0M
    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
311
51.0M
    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
312
51.7M
    case SPV_OPERAND_TYPE_CAPABILITY:
313
51.7M
    case SPV_OPERAND_TYPE_RAY_FLAGS:
314
51.7M
    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
315
51.7M
    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
316
51.7M
    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
317
51.7M
    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
318
51.7M
    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
319
51.7M
    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
320
51.7M
    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
321
51.7M
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
322
51.7M
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
323
51.7M
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
324
51.7M
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
325
51.7M
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
326
51.9M
    case SPV_OPERAND_TYPE_FPDENORM_MODE:
327
52.1M
    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
328
52.1M
    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
329
52.1M
    case SPV_OPERAND_TYPE_OVERFLOW_MODES:
330
52.1M
    case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
331
52.1M
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
332
52.1M
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
333
52.1M
    case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
334
52.1M
    case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
335
52.3M
    case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
336
52.3M
    case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
337
52.4M
    case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
338
52.4M
    case SPV_OPERAND_TYPE_FPENCODING:
339
52.4M
    case SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE:
340
52.4M
    case SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT:
341
52.4M
    case SPV_OPERAND_TYPE_COMPONENT_TYPE:
342
52.4M
    case SPV_OPERAND_TYPE_KERNEL_PROPERTY_FLAGS:
343
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_BUILD_IDENTIFIER_FLAGS:
344
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
345
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_COMPOSITE_TYPE:
346
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_IMPORTED_ENTITY:
347
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_INFO_FLAGS:
348
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_OPERATION:
349
52.4M
    case SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_TYPE_QUALIFIER:
350
52.4M
      return true;
351
0
    default:
352
0
      break;
353
52.4M
  }
354
0
  return false;
355
52.4M
}
356
357
76.8M
bool spvOperandIsConcreteMask(spv_operand_type_t type) {
358
76.8M
  switch (type) {
359
4.65k
    case SPV_OPERAND_TYPE_IMAGE:
360
361k
    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
361
1.10M
    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
362
1.76M
    case SPV_OPERAND_TYPE_LOOP_CONTROL:
363
2.12M
    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
364
2.93M
    case SPV_OPERAND_TYPE_MEMORY_ACCESS:
365
2.93M
    case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
366
2.93M
    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
367
2.93M
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
368
2.93M
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
369
2.94M
    case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
370
2.94M
    case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
371
2.94M
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
372
3.49M
    case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
373
3.49M
    case SPV_OPERAND_TYPE_TENSOR_OPERANDS:
374
3.49M
      return true;
375
73.3M
    default:
376
73.3M
      break;
377
76.8M
  }
378
73.3M
  return false;
379
76.8M
}
380
381
79.7M
bool spvOperandIsOptional(spv_operand_type_t type) {
382
79.7M
  switch (type) {
383
1.61M
    case SPV_OPERAND_TYPE_OPTIONAL_ID:
384
1.64M
    case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
385
6.20M
    case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
386
6.21M
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
387
14.7M
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
388
14.7M
    case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
389
14.9M
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
390
15.0M
    case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
391
15.0M
    case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
392
15.0M
    case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
393
15.0M
    case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
394
23.6M
    case SPV_OPERAND_TYPE_OPTIONAL_CIV:
395
23.6M
    case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
396
24.0M
    case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
397
24.0M
    case SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS:
398
24.1M
    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
399
24.1M
      return true;
400
55.6M
    default:
401
55.6M
      break;
402
79.7M
  }
403
  // Any variable operand is also optional.
404
55.6M
  return spvOperandIsVariable(type);
405
79.7M
}
406
407
55.6M
bool spvOperandIsVariable(spv_operand_type_t type) {
408
55.6M
  switch (type) {
409
45.0M
    case SPV_OPERAND_TYPE_VARIABLE_ID:
410
46.1M
    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
411
46.2M
    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
412
54.1M
    case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
413
54.1M
    case SPV_OPERAND_TYPE_VARIABLE_CAPABILITY:
414
54.1M
      return true;
415
1.51M
    default:
416
1.51M
      break;
417
55.6M
  }
418
1.51M
  return false;
419
55.6M
}
420
421
bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
422
300M
                                  spv_operand_pattern_t* pattern) {
423
300M
  switch (type) {
424
36.0M
    case SPV_OPERAND_TYPE_VARIABLE_ID:
425
36.0M
      pattern->push_back(type);
426
36.0M
      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
427
36.0M
      return true;
428
16.3M
    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
429
16.3M
      pattern->push_back(type);
430
16.3M
      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
431
16.3M
      return true;
432
11.7M
    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
433
      // Represents Zero or more (Literal number, Id) pairs,
434
      // where the literal number must be a scalar integer.
435
11.7M
      pattern->push_back(type);
436
11.7M
      pattern->push_back(SPV_OPERAND_TYPE_ID);
437
11.7M
      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
438
11.7M
      return true;
439
387k
    case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
440
      // Represents Zero or more (Id, Literal number) pairs.
441
387k
      pattern->push_back(type);
442
387k
      pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
443
387k
      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
444
387k
      return true;
445
195k
    case SPV_OPERAND_TYPE_VARIABLE_CAPABILITY:
446
195k
      pattern->push_back(type);
447
195k
      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY);
448
195k
      return true;
449
235M
    default:
450
235M
      break;
451
300M
  }
452
235M
  return false;
453
300M
}
454
455
spv_operand_type_t spvTakeFirstMatchableOperand(
456
229M
    spv_operand_pattern_t* pattern) {
457
229M
  assert(!pattern->empty());
458
229M
  spv_operand_type_t result;
459
294M
  do {
460
294M
    result = pattern->back();
461
294M
    pattern->pop_back();
462
294M
  } while (spvExpandOperandSequenceOnce(result, pattern));
463
229M
  return result;
464
229M
}
465
466
spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
467
55.3k
    const spv_operand_pattern_t& pattern) {
468
55.3k
  auto it =
469
55.3k
      std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
470
55.3k
  if (it != pattern.crend()) {
471
10.2k
    spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
472
10.2k
                                           SPV_OPERAND_TYPE_OPTIONAL_CIV);
473
10.2k
    alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
474
10.2k
    return alternatePattern;
475
10.2k
  }
476
477
  // No result-id found, so just expect CIVs.
478
45.1k
  return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
479
55.3k
}
480
481
444M
bool spvIsIdType(spv_operand_type_t type) {
482
444M
  switch (type) {
483
268M
    case SPV_OPERAND_TYPE_ID:
484
317M
    case SPV_OPERAND_TYPE_TYPE_ID:
485
376M
    case SPV_OPERAND_TYPE_RESULT_ID:
486
376M
    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
487
377M
    case SPV_OPERAND_TYPE_SCOPE_ID:
488
377M
      return true;
489
67.7M
    default:
490
67.7M
      return false;
491
444M
  }
492
444M
}
493
494
139M
bool spvIsInIdType(spv_operand_type_t type) {
495
139M
  if (!spvIsIdType(type)) {
496
    // If it is not an ID it cannot be an input ID.
497
6.58M
    return false;
498
6.58M
  }
499
133M
  switch (type) {
500
    // Deny non-input IDs.
501
25.0M
    case SPV_OPERAND_TYPE_TYPE_ID:
502
54.1M
    case SPV_OPERAND_TYPE_RESULT_ID:
503
54.1M
      return false;
504
78.9M
    default:
505
78.9M
      return true;
506
133M
  }
507
133M
}
508
509
std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
510
14.0M
    spv::Op opcode) {
511
14.0M
  std::function<bool(unsigned index)> out;
512
14.0M
  if (spvOpcodeGeneratesType(opcode)) {
513
    // All types can use forward pointers.
514
305k
    out = [](unsigned) { return true; };
515
305k
    return out;
516
305k
  }
517
13.7M
  switch (opcode) {
518
38.5k
    case spv::Op::OpExecutionMode:
519
38.5k
    case spv::Op::OpExecutionModeId:
520
64.7k
    case spv::Op::OpEntryPoint:
521
164k
    case spv::Op::OpName:
522
174k
    case spv::Op::OpMemberName:
523
248k
    case spv::Op::OpSelectionMerge:
524
659k
    case spv::Op::OpDecorate:
525
667k
    case spv::Op::OpMemberDecorate:
526
667k
    case spv::Op::OpMemberDecorateIdEXT:
527
667k
    case spv::Op::OpDecorateId:
528
667k
    case spv::Op::OpDecorateStringGOOGLE:
529
667k
    case spv::Op::OpMemberDecorateStringGOOGLE:
530
887k
    case spv::Op::OpBranch:
531
959k
    case spv::Op::OpLoopMerge:
532
959k
    case spv::Op::OpConditionalEntryPointINTEL:
533
959k
    case spv::Op::OpConditionalCapabilityINTEL:
534
959k
    case spv::Op::OpConditionalExtensionINTEL:
535
2.28M
      out = [](unsigned) { return true; };
536
959k
      break;
537
8.54M
    case spv::Op::OpGroupDecorate:
538
10.1M
    case spv::Op::OpGroupMemberDecorate:
539
10.2M
    case spv::Op::OpBranchConditional:
540
10.2M
    case spv::Op::OpSwitch:
541
10.2M
      out = [](unsigned index) { return index != 0; };
542
10.2M
      break;
543
544
31.7k
    case spv::Op::OpFunctionCall:
545
      // The Function parameter.
546
31.7k
      out = [](unsigned index) { return index == 2; };
547
31.7k
      break;
548
549
70.3k
    case spv::Op::OpPhi:
550
70.3k
      out = [](unsigned index) { return index > 1; };
551
70.3k
      break;
552
553
4
    case spv::Op::OpEnqueueKernel:
554
      // The Invoke parameter.
555
4
      out = [](unsigned index) { return index == 8; };
556
4
      break;
557
558
3
    case spv::Op::OpGetKernelNDrangeSubGroupCount:
559
4
    case spv::Op::OpGetKernelNDrangeMaxSubGroupSize:
560
      // The Invoke parameter.
561
4
      out = [](unsigned index) { return index == 3; };
562
4
      break;
563
564
2
    case spv::Op::OpGetKernelWorkGroupSize:
565
8
    case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple:
566
      // The Invoke parameter.
567
8
      out = [](unsigned index) { return index == 2; };
568
8
      break;
569
832
    case spv::Op::OpTypeForwardPointer:
570
832
      out = [](unsigned index) { return index == 0; };
571
832
      break;
572
0
    case spv::Op::OpTypeArray:
573
0
      out = [](unsigned index) { return index == 1; };
574
0
      break;
575
2
    case spv::Op::OpCooperativeMatrixPerElementOpNV:
576
2
      out = [](unsigned index) { return index == 3; };
577
2
      break;
578
5
    case spv::Op::OpCooperativeMatrixReduceNV:
579
5
      out = [](unsigned index) { return index == 4; };
580
5
      break;
581
1
    case spv::Op::OpCooperativeMatrixLoadTensorNV:
582
      // approximate, due to variable operands
583
1
      out = [](unsigned index) { return index > 6; };
584
1
      break;
585
20
    case spv::Op::OpGraphEntryPointARM:
586
25
      out = [](unsigned index) { return index == 0; };
587
20
      break;
588
2.47M
    default:
589
2.47M
      out = [](unsigned) { return false; };
590
2.47M
      break;
591
13.7M
  }
592
13.7M
  return out;
593
13.7M
}
594
595
std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
596
75
    spv::Op opcode, spv_ext_inst_type_t ext_type, uint32_t key) {
597
  // The Vulkan debug info extended instruction set is non-semantic so allows no
598
  // forward references except if used through OpExtInstWithForwardRefsKHR.
599
75
  if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
600
23
    return [opcode](unsigned) {
601
0
      return opcode == spv::Op::OpExtInstWithForwardRefsKHR;
602
0
    };
603
23
  }
604
605
  // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
606
  // references for debug info instructions are still in discussion. We must
607
  // update the following lines of code when we conclude the spec.
608
52
  std::function<bool(unsigned index)> out;
609
52
  if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
610
12
    switch (OpenCLDebugInfo100Instructions(key)) {
611
0
      case OpenCLDebugInfo100DebugFunction:
612
0
        out = [](unsigned index) { return index == 13; };
613
0
        break;
614
0
      case OpenCLDebugInfo100DebugTypeComposite:
615
0
        out = [](unsigned index) { return index >= 13; };
616
0
        break;
617
12
      default:
618
12
        out = [](unsigned) { return false; };
619
12
        break;
620
12
    }
621
40
  } else {
622
40
    switch (DebugInfoInstructions(key)) {
623
0
      case DebugInfoDebugFunction:
624
0
        out = [](unsigned index) { return index == 13; };
625
0
        break;
626
7
      case DebugInfoDebugTypeComposite:
627
7
        out = [](unsigned index) { return index >= 12; };
628
7
        break;
629
33
      default:
630
33
        out = [](unsigned) { return false; };
631
33
        break;
632
40
    }
633
40
  }
634
52
  return out;
635
52
}
636
637
39.2k
spv_fp_encoding_t spvFPEncodingFromOperandFPEncoding(spv::FPEncoding encoding) {
638
39.2k
  switch (encoding) {
639
18.3k
    case spv::FPEncoding::BFloat16KHR:
640
18.3k
      return SPV_FP_ENCODING_BFLOAT16;
641
9.84k
    case spv::FPEncoding::Float8E4M3EXT:
642
9.84k
      return SPV_FP_ENCODING_FLOAT8_E4M3;
643
11.1k
    case spv::FPEncoding::Float8E5M2EXT:
644
11.1k
      return SPV_FP_ENCODING_FLOAT8_E5M2;
645
0
    case spv::FPEncoding::Max:
646
0
      break;
647
39.2k
  }
648
0
  return SPV_FP_ENCODING_UNKNOWN;
649
39.2k
}