Coverage Report

Created: 2026-06-08 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spirv-tools/source/opcode.cpp
Line
Count
Source
1
// Copyright (c) 2015-2022 The Khronos Group Inc.
2
// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All
3
// rights 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/opcode.h"
18
19
#include <assert.h>
20
#include <string.h>
21
22
#include <algorithm>
23
#include <cstdlib>
24
25
#include "source/instruction.h"
26
#include "source/macro.h"
27
#include "source/spirv_constant.h"
28
#include "source/spirv_endian.h"
29
#include "source/spirv_target_env.h"
30
#include "source/table2.h"
31
#include "spirv-tools/libspirv.h"
32
33
namespace {
34
35
// Represents a vendor tool entry in the SPIR-V XML Registry.
36
struct VendorTool {
37
  uint32_t value;
38
  const char* vendor;
39
  const char* tool;         // Might be empty string.
40
  const char* vendor_tool;  // Combination of vendor and tool.
41
};
42
43
const VendorTool vendor_tools[] = {
44
#include "generators.inc"
45
};
46
47
}  // anonymous namespace
48
49
// TODO(dneto): Move this to another file.  It doesn't belong with opcode
50
// processing.
51
0
const char* spvGeneratorStr(uint32_t generator) {
52
0
  auto where = std::find_if(
53
0
      std::begin(vendor_tools), std::end(vendor_tools),
54
0
      [generator](const VendorTool& vt) { return generator == vt.value; });
55
0
  if (where != std::end(vendor_tools)) return where->vendor_tool;
56
0
  return "Unknown";
57
0
}
58
59
642k
uint32_t spvOpcodeMake(uint16_t wordCount, spv::Op opcode) {
60
642k
  return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
61
642k
}
62
63
void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount,
64
76.4M
                    uint16_t* pOpcode) {
65
76.4M
  if (pWordCount) {
66
76.4M
    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
67
76.4M
  }
68
76.4M
  if (pOpcode) {
69
76.4M
    *pOpcode = 0x0000ffff & word;
70
76.4M
  }
71
76.4M
}
72
73
void spvInstructionCopy(const uint32_t* words, const spv::Op opcode,
74
                        const uint16_t wordCount, const spv_endianness_t endian,
75
0
                        spv_instruction_t* pInst) {
76
0
  pInst->opcode = opcode;
77
0
  pInst->words.resize(wordCount);
78
0
  for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
79
0
    pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
80
0
    if (!wordIndex) {
81
0
      uint16_t thisWordCount;
82
0
      uint16_t thisOpcode;
83
0
      spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
84
0
      assert(opcode == static_cast<spv::Op>(thisOpcode) &&
85
0
             wordCount == thisWordCount && "Endianness failed!");
86
0
    }
87
0
  }
88
0
}
89
90
211k
const char* spvOpcodeString(const uint32_t opcode) {
91
211k
  const spvtools::InstructionDesc* desc = nullptr;
92
211k
  if (SPV_SUCCESS !=
93
211k
      spvtools::LookupOpcode(static_cast<spv::Op>(opcode), &desc)) {
94
0
    assert(0 && "Unreachable!");
95
0
    return "unknown";
96
0
  }
97
211k
  return desc->name().data();
98
211k
}
99
100
211k
const char* spvOpcodeString(const spv::Op opcode) {
101
211k
  return spvOpcodeString(static_cast<uint32_t>(opcode));
102
211k
}
103
104
62.0k
int32_t spvOpcodeIsScalarType(const spv::Op opcode) {
105
62.0k
  switch (opcode) {
106
12.1k
    case spv::Op::OpTypeInt:
107
46.7k
    case spv::Op::OpTypeFloat:
108
51.3k
    case spv::Op::OpTypeBool:
109
51.3k
      return true;
110
10.7k
    default:
111
10.7k
      return false;
112
62.0k
  }
113
62.0k
}
114
115
628k
int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) {
116
628k
  switch (opcode) {
117
524
    case spv::Op::OpSpecConstantTrue:
118
1.02k
    case spv::Op::OpSpecConstantFalse:
119
3.97k
    case spv::Op::OpSpecConstant:
120
5.69k
    case spv::Op::OpSpecConstantComposite:
121
5.69k
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
122
5.69k
    case spv::Op::OpSpecConstantOp:
123
5.69k
    case spv::Op::OpSpecConstantArchitectureINTEL:
124
5.69k
    case spv::Op::OpSpecConstantTargetINTEL:
125
5.69k
    case spv::Op::OpSpecConstantCapabilitiesINTEL:
126
5.69k
    case spv::Op::OpSpecConstantDataKHR:
127
5.69k
      return true;
128
622k
    default:
129
622k
      return false;
130
628k
  }
131
628k
}
132
133
63.0M
int32_t spvOpcodeIsConstant(const spv::Op opcode) {
134
63.0M
  switch (opcode) {
135
87.9k
    case spv::Op::OpConstantTrue:
136
137k
    case spv::Op::OpConstantFalse:
137
2.73M
    case spv::Op::OpConstant:
138
3.22M
    case spv::Op::OpConstantComposite:
139
3.22M
    case spv::Op::OpConstantCompositeReplicateEXT:
140
3.22M
    case spv::Op::OpConstantSampler:
141
3.25M
    case spv::Op::OpConstantNull:
142
3.25M
    case spv::Op::OpConstantFunctionPointerINTEL:
143
3.25M
    case spv::Op::OpConstantStringAMDX:
144
3.26M
    case spv::Op::OpSpecConstantTrue:
145
3.27M
    case spv::Op::OpSpecConstantFalse:
146
3.29M
    case spv::Op::OpSpecConstant:
147
3.29M
    case spv::Op::OpSpecConstantComposite:
148
3.29M
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
149
3.29M
    case spv::Op::OpSpecConstantOp:
150
3.29M
    case spv::Op::OpSpecConstantStringAMDX:
151
3.29M
    case spv::Op::OpGraphConstantARM:
152
3.29M
    case spv::Op::OpAsmTargetINTEL:
153
3.29M
    case spv::Op::OpAsmINTEL:
154
3.29M
    case spv::Op::OpSpecConstantArchitectureINTEL:
155
3.29M
    case spv::Op::OpSpecConstantTargetINTEL:
156
3.29M
    case spv::Op::OpSpecConstantCapabilitiesINTEL:
157
3.29M
    case spv::Op::OpConstantSizeOfEXT:
158
3.29M
    case spv::Op::OpConstantDataKHR:
159
3.29M
    case spv::Op::OpSpecConstantDataKHR:
160
3.29M
      return true;
161
59.7M
    default:
162
59.7M
      return false;
163
63.0M
  }
164
63.0M
}
165
166
136k
bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) {
167
136k
  return opcode == spv::Op::OpUndef || opcode == spv::Op::OpPoisonKHR ||
168
136k
         spvOpcodeIsConstant(opcode);
169
136k
}
170
171
251k
int32_t spvOpcodeIsComposite(const spv::Op opcode) {
172
251k
  switch (opcode) {
173
150k
    case spv::Op::OpTypeVector:
174
150k
    case spv::Op::OpTypeMatrix:
175
160k
    case spv::Op::OpTypeArray:
176
163k
    case spv::Op::OpTypeStruct:
177
164k
    case spv::Op::OpTypeRuntimeArray:
178
164k
    case spv::Op::OpTypeCooperativeMatrixNV:
179
164k
    case spv::Op::OpTypeCooperativeMatrixKHR:
180
164k
    case spv::Op::OpTypeVectorIdEXT:
181
164k
      return true;
182
87.0k
    default:
183
87.0k
      return false;
184
251k
  }
185
251k
}
186
187
0
bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) {
188
0
  switch (opcode) {
189
0
    case spv::Op::OpVariable:
190
0
    case spv::Op::OpUntypedVariableKHR:
191
0
    case spv::Op::OpAccessChain:
192
0
    case spv::Op::OpInBoundsAccessChain:
193
0
    case spv::Op::OpUntypedAccessChainKHR:
194
0
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
195
0
    case spv::Op::OpBufferPointerEXT:
196
0
    case spv::Op::OpFunctionParameter:
197
0
    case spv::Op::OpImageTexelPointer:
198
0
    case spv::Op::OpUntypedImageTexelPointerEXT:
199
0
    case spv::Op::OpCopyObject:
200
0
    case spv::Op::OpAllocateNodePayloadsAMDX:
201
0
    case spv::Op::OpSelect:
202
0
    case spv::Op::OpPhi:
203
0
    case spv::Op::OpFunctionCall:
204
0
    case spv::Op::OpPtrAccessChain:
205
0
    case spv::Op::OpUntypedPtrAccessChainKHR:
206
0
    case spv::Op::OpLoad:
207
0
    case spv::Op::OpConstantNull:
208
0
    case spv::Op::OpRawAccessChainNV:
209
0
      return true;
210
0
    default:
211
0
      return false;
212
0
  }
213
0
}
214
215
563k
int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
216
563k
  switch (opcode) {
217
373k
    case spv::Op::OpVariable:
218
373k
    case spv::Op::OpUntypedVariableKHR:
219
533k
    case spv::Op::OpAccessChain:
220
535k
    case spv::Op::OpInBoundsAccessChain:
221
535k
    case spv::Op::OpUntypedAccessChainKHR:
222
535k
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
223
535k
    case spv::Op::OpBufferPointerEXT:
224
563k
    case spv::Op::OpFunctionParameter:
225
563k
    case spv::Op::OpImageTexelPointer:
226
563k
    case spv::Op::OpUntypedImageTexelPointerEXT:
227
563k
    case spv::Op::OpCopyObject:
228
563k
    case spv::Op::OpRawAccessChainNV:
229
563k
    case spv::Op::OpAllocateNodePayloadsAMDX:
230
563k
      return true;
231
36
    default:
232
36
      return false;
233
563k
  }
234
563k
}
235
236
180M
int32_t spvOpcodeGeneratesType(spv::Op op) {
237
180M
  switch (op) {
238
944k
    case spv::Op::OpTypeVoid:
239
1.44M
    case spv::Op::OpTypeBool:
240
2.82M
    case spv::Op::OpTypeInt:
241
3.80M
    case spv::Op::OpTypeFloat:
242
4.90M
    case spv::Op::OpTypeVector:
243
5.05M
    case spv::Op::OpTypeMatrix:
244
5.13M
    case spv::Op::OpTypeImage:
245
5.16M
    case spv::Op::OpTypeSampler:
246
5.23M
    case spv::Op::OpTypeSampledImage:
247
5.48M
    case spv::Op::OpTypeArray:
248
5.52M
    case spv::Op::OpTypeRuntimeArray:
249
6.23M
    case spv::Op::OpTypeStruct:
250
6.25M
    case spv::Op::OpTypeOpaque:
251
8.79M
    case spv::Op::OpTypePointer:
252
9.72M
    case spv::Op::OpTypeFunction:
253
9.73M
    case spv::Op::OpTypeEvent:
254
9.74M
    case spv::Op::OpTypeDeviceEvent:
255
9.75M
    case spv::Op::OpTypeReserveId:
256
9.76M
    case spv::Op::OpTypeQueue:
257
9.76M
    case spv::Op::OpTypePipe:
258
9.77M
    case spv::Op::OpTypePipeStorage:
259
9.77M
    case spv::Op::OpTypeNamedBarrier:
260
9.77M
    case spv::Op::OpTypeAccelerationStructureNV:
261
9.77M
    case spv::Op::OpTypeCooperativeMatrixNV:
262
9.77M
    case spv::Op::OpTypeCooperativeMatrixKHR:
263
9.77M
    case spv::Op::OpTypeVectorIdEXT:
264
    // case spv::Op::OpTypeAccelerationStructureKHR: covered by
265
    // spv::Op::OpTypeAccelerationStructureNV
266
9.77M
    case spv::Op::OpTypeRayQueryKHR:
267
9.78M
    case spv::Op::OpTypeHitObjectNV:
268
9.78M
    case spv::Op::OpTypeHitObjectEXT:
269
9.78M
    case spv::Op::OpTypeUntypedPointerKHR:
270
9.78M
    case spv::Op::OpTypeNodePayloadArrayAMDX:
271
9.78M
    case spv::Op::OpTypeTensorLayoutNV:
272
9.78M
    case spv::Op::OpTypeTensorViewNV:
273
9.78M
    case spv::Op::OpTypeTensorARM:
274
9.78M
    case spv::Op::OpTypeTaskSequenceINTEL:
275
9.78M
    case spv::Op::OpTypeGraphARM:
276
9.78M
    case spv::Op::OpTypeBufferEXT:
277
9.78M
      return true;
278
170M
    default:
279
      // In particular, OpTypeForwardPointer does not generate a type,
280
      // but declares a storage class for a pointer type generated
281
      // by a different instruction.
282
170M
      break;
283
180M
  }
284
170M
  return 0;
285
180M
}
286
287
47.8M
bool spvOpcodeIsDecoration(const spv::Op opcode) {
288
47.8M
  switch (opcode) {
289
934k
    case spv::Op::OpDecorate:
290
934k
    case spv::Op::OpDecorateId:
291
934k
    case spv::Op::OpMemberDecorate:
292
934k
    case spv::Op::OpMemberDecorateIdEXT:
293
9.81M
    case spv::Op::OpGroupDecorate:
294
11.4M
    case spv::Op::OpGroupMemberDecorate:
295
11.4M
    case spv::Op::OpDecorateStringGOOGLE:
296
11.4M
    case spv::Op::OpMemberDecorateStringGOOGLE:
297
11.4M
      return true;
298
36.4M
    default:
299
36.4M
      break;
300
47.8M
  }
301
36.4M
  return false;
302
47.8M
}
303
304
7.21M
bool spvOpcodeIsLoad(const spv::Op opcode) {
305
7.21M
  switch (opcode) {
306
1.30M
    case spv::Op::OpLoad:
307
1.30M
    case spv::Op::OpImageSampleExplicitLod:
308
1.65M
    case spv::Op::OpImageSampleImplicitLod:
309
1.65M
    case spv::Op::OpImageSampleDrefImplicitLod:
310
1.65M
    case spv::Op::OpImageSampleDrefExplicitLod:
311
1.65M
    case spv::Op::OpImageSampleProjImplicitLod:
312
1.65M
    case spv::Op::OpImageSampleProjExplicitLod:
313
1.65M
    case spv::Op::OpImageSampleProjDrefImplicitLod:
314
1.65M
    case spv::Op::OpImageSampleProjDrefExplicitLod:
315
1.65M
    case spv::Op::OpImageSampleFootprintNV:
316
1.65M
    case spv::Op::OpImageFetch:
317
1.65M
    case spv::Op::OpImageGather:
318
1.65M
    case spv::Op::OpImageDrefGather:
319
1.65M
    case spv::Op::OpImageRead:
320
1.65M
    case spv::Op::OpImageSparseSampleImplicitLod:
321
1.65M
    case spv::Op::OpImageSparseSampleExplicitLod:
322
1.65M
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
323
1.65M
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
324
1.65M
    case spv::Op::OpImageSparseFetch:
325
1.65M
    case spv::Op::OpImageSparseGather:
326
1.65M
    case spv::Op::OpImageSparseDrefGather:
327
1.65M
    case spv::Op::OpImageSparseRead:
328
1.65M
      return true;
329
5.55M
    default:
330
5.55M
      return false;
331
7.21M
  }
332
7.21M
}
333
334
59.1M
bool spvOpcodeIsBranch(spv::Op opcode) {
335
59.1M
  switch (opcode) {
336
10.1M
    case spv::Op::OpBranch:
337
13.4M
    case spv::Op::OpBranchConditional:
338
13.9M
    case spv::Op::OpSwitch:
339
13.9M
      return true;
340
45.1M
    default:
341
45.1M
      return false;
342
59.1M
  }
343
59.1M
}
344
345
16.9M
bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) {
346
16.9M
  switch (opcode) {
347
129
    case spv::Op::OpAtomicLoad:
348
137
    case spv::Op::OpAtomicExchange:
349
137
    case spv::Op::OpAtomicCompareExchange:
350
137
    case spv::Op::OpAtomicCompareExchangeWeak:
351
180
    case spv::Op::OpAtomicIIncrement:
352
231
    case spv::Op::OpAtomicIDecrement:
353
243
    case spv::Op::OpAtomicIAdd:
354
243
    case spv::Op::OpAtomicFAddEXT:
355
255
    case spv::Op::OpAtomicISub:
356
267
    case spv::Op::OpAtomicSMin:
357
279
    case spv::Op::OpAtomicUMin:
358
279
    case spv::Op::OpAtomicFMinEXT:
359
292
    case spv::Op::OpAtomicSMax:
360
300
    case spv::Op::OpAtomicUMax:
361
300
    case spv::Op::OpAtomicFMaxEXT:
362
314
    case spv::Op::OpAtomicAnd:
363
316
    case spv::Op::OpAtomicOr:
364
324
    case spv::Op::OpAtomicXor:
365
324
    case spv::Op::OpAtomicFlagTestAndSet:
366
324
      return true;
367
16.9M
    default:
368
16.9M
      return false;
369
16.9M
  }
370
16.9M
}
371
372
120
bool spvOpcodeIsAtomicOp(const spv::Op opcode) {
373
120
  return (spvOpcodeIsAtomicWithLoad(opcode) ||
374
33
          opcode == spv::Op::OpAtomicStore ||
375
15
          opcode == spv::Op::OpAtomicFlagClear);
376
120
}
377
378
32.5M
bool spvOpcodeIsReturn(spv::Op opcode) {
379
32.5M
  switch (opcode) {
380
294k
    case spv::Op::OpReturn:
381
417k
    case spv::Op::OpReturnValue:
382
417k
      return true;
383
32.1M
    default:
384
32.1M
      return false;
385
32.5M
  }
386
32.5M
}
387
388
31.9M
bool spvOpcodeIsAbort(spv::Op opcode) {
389
31.9M
  switch (opcode) {
390
100k
    case spv::Op::OpKill:
391
262k
    case spv::Op::OpUnreachable:
392
262k
    case spv::Op::OpTerminateInvocation:
393
262k
    case spv::Op::OpTerminateRayKHR:
394
262k
    case spv::Op::OpIgnoreIntersectionKHR:
395
262k
    case spv::Op::OpEmitMeshTasksEXT:
396
262k
    case spv::Op::OpAbortKHR:
397
262k
      return true;
398
31.6M
    default:
399
31.6M
      return false;
400
31.9M
  }
401
31.9M
}
402
403
32.0M
bool spvOpcodeIsReturnOrAbort(spv::Op opcode) {
404
32.0M
  return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
405
32.0M
}
406
407
39.6M
bool spvOpcodeIsBlockTerminator(spv::Op opcode) {
408
39.6M
  return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
409
39.6M
}
410
411
0
bool spvOpcodeIsBaseOpaqueType(spv::Op opcode) {
412
0
  switch (opcode) {
413
0
    case spv::Op::OpTypeImage:
414
0
    case spv::Op::OpTypeSampler:
415
0
    case spv::Op::OpTypeSampledImage:
416
0
    case spv::Op::OpTypeOpaque:
417
0
    case spv::Op::OpTypeEvent:
418
0
    case spv::Op::OpTypeDeviceEvent:
419
0
    case spv::Op::OpTypeReserveId:
420
0
    case spv::Op::OpTypeQueue:
421
0
    case spv::Op::OpTypePipe:
422
0
    case spv::Op::OpTypeForwardPointer:
423
0
    case spv::Op::OpTypePipeStorage:
424
0
    case spv::Op::OpTypeNamedBarrier:
425
0
      return true;
426
0
    default:
427
0
      return false;
428
0
  }
429
0
}
430
431
14.6M
bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) {
432
14.6M
  switch (opcode) {
433
23
    case spv::Op::OpGroupNonUniformElect:
434
23
    case spv::Op::OpGroupNonUniformAll:
435
23
    case spv::Op::OpGroupNonUniformAny:
436
23
    case spv::Op::OpGroupNonUniformAllEqual:
437
23
    case spv::Op::OpGroupNonUniformBroadcast:
438
23
    case spv::Op::OpGroupNonUniformBroadcastFirst:
439
23
    case spv::Op::OpGroupNonUniformBallot:
440
23
    case spv::Op::OpGroupNonUniformInverseBallot:
441
23
    case spv::Op::OpGroupNonUniformBallotBitExtract:
442
23
    case spv::Op::OpGroupNonUniformBallotBitCount:
443
23
    case spv::Op::OpGroupNonUniformBallotFindLSB:
444
23
    case spv::Op::OpGroupNonUniformBallotFindMSB:
445
23
    case spv::Op::OpGroupNonUniformShuffle:
446
23
    case spv::Op::OpGroupNonUniformShuffleXor:
447
23
    case spv::Op::OpGroupNonUniformShuffleUp:
448
23
    case spv::Op::OpGroupNonUniformShuffleDown:
449
23
    case spv::Op::OpGroupNonUniformIAdd:
450
23
    case spv::Op::OpGroupNonUniformFAdd:
451
23
    case spv::Op::OpGroupNonUniformIMul:
452
23
    case spv::Op::OpGroupNonUniformFMul:
453
23
    case spv::Op::OpGroupNonUniformSMin:
454
23
    case spv::Op::OpGroupNonUniformUMin:
455
23
    case spv::Op::OpGroupNonUniformFMin:
456
23
    case spv::Op::OpGroupNonUniformSMax:
457
23
    case spv::Op::OpGroupNonUniformUMax:
458
23
    case spv::Op::OpGroupNonUniformFMax:
459
23
    case spv::Op::OpGroupNonUniformBitwiseAnd:
460
23
    case spv::Op::OpGroupNonUniformBitwiseOr:
461
23
    case spv::Op::OpGroupNonUniformBitwiseXor:
462
23
    case spv::Op::OpGroupNonUniformLogicalAnd:
463
23
    case spv::Op::OpGroupNonUniformLogicalOr:
464
23
    case spv::Op::OpGroupNonUniformLogicalXor:
465
23
    case spv::Op::OpGroupNonUniformQuadBroadcast:
466
23
    case spv::Op::OpGroupNonUniformQuadSwap:
467
23
    case spv::Op::OpGroupNonUniformRotateKHR:
468
23
    case spv::Op::OpGroupNonUniformQuadAllKHR:
469
23
    case spv::Op::OpGroupNonUniformQuadAnyKHR:
470
23
      return true;
471
14.6M
    default:
472
14.6M
      return false;
473
14.6M
  }
474
14.6M
}
475
476
1.36M
bool spvOpcodeIsScalarizable(spv::Op opcode) {
477
1.36M
  switch (opcode) {
478
127k
    case spv::Op::OpPhi:
479
127k
    case spv::Op::OpCopyObject:
480
127k
    case spv::Op::OpConvertFToU:
481
135k
    case spv::Op::OpConvertFToS:
482
150k
    case spv::Op::OpConvertSToF:
483
151k
    case spv::Op::OpConvertUToF:
484
151k
    case spv::Op::OpUConvert:
485
151k
    case spv::Op::OpSConvert:
486
151k
    case spv::Op::OpFConvert:
487
151k
    case spv::Op::OpQuantizeToF16:
488
151k
    case spv::Op::OpVectorInsertDynamic:
489
152k
    case spv::Op::OpSNegate:
490
152k
    case spv::Op::OpFNegate:
491
180k
    case spv::Op::OpIAdd:
492
362k
    case spv::Op::OpFAdd:
493
379k
    case spv::Op::OpISub:
494
407k
    case spv::Op::OpFSub:
495
411k
    case spv::Op::OpIMul:
496
478k
    case spv::Op::OpFMul:
497
478k
    case spv::Op::OpUDiv:
498
482k
    case spv::Op::OpSDiv:
499
511k
    case spv::Op::OpFDiv:
500
511k
    case spv::Op::OpUMod:
501
516k
    case spv::Op::OpSRem:
502
518k
    case spv::Op::OpSMod:
503
520k
    case spv::Op::OpFRem:
504
536k
    case spv::Op::OpFMod:
505
693k
    case spv::Op::OpVectorTimesScalar:
506
693k
    case spv::Op::OpIAddCarry:
507
693k
    case spv::Op::OpISubBorrow:
508
693k
    case spv::Op::OpUMulExtended:
509
693k
    case spv::Op::OpSMulExtended:
510
694k
    case spv::Op::OpShiftRightLogical:
511
694k
    case spv::Op::OpShiftRightArithmetic:
512
695k
    case spv::Op::OpShiftLeftLogical:
513
703k
    case spv::Op::OpBitwiseOr:
514
707k
    case spv::Op::OpBitwiseAnd:
515
708k
    case spv::Op::OpNot:
516
708k
    case spv::Op::OpBitFieldInsert:
517
709k
    case spv::Op::OpBitFieldSExtract:
518
709k
    case spv::Op::OpBitFieldUExtract:
519
709k
    case spv::Op::OpBitReverse:
520
711k
    case spv::Op::OpBitCount:
521
712k
    case spv::Op::OpIsNan:
522
713k
    case spv::Op::OpIsInf:
523
713k
    case spv::Op::OpIsFinite:
524
713k
    case spv::Op::OpIsNormal:
525
713k
    case spv::Op::OpSignBitSet:
526
713k
    case spv::Op::OpLessOrGreater:
527
713k
    case spv::Op::OpOrdered:
528
713k
    case spv::Op::OpUnordered:
529
713k
    case spv::Op::OpLogicalEqual:
530
713k
    case spv::Op::OpLogicalNotEqual:
531
713k
    case spv::Op::OpLogicalOr:
532
714k
    case spv::Op::OpLogicalAnd:
533
717k
    case spv::Op::OpLogicalNot:
534
722k
    case spv::Op::OpSelect:
535
736k
    case spv::Op::OpIEqual:
536
740k
    case spv::Op::OpINotEqual:
537
743k
    case spv::Op::OpUGreaterThan:
538
749k
    case spv::Op::OpSGreaterThan:
539
750k
    case spv::Op::OpUGreaterThanEqual:
540
753k
    case spv::Op::OpSGreaterThanEqual:
541
754k
    case spv::Op::OpULessThan:
542
768k
    case spv::Op::OpSLessThan:
543
771k
    case spv::Op::OpULessThanEqual:
544
782k
    case spv::Op::OpSLessThanEqual:
545
783k
    case spv::Op::OpFOrdEqual:
546
784k
    case spv::Op::OpFUnordEqual:
547
786k
    case spv::Op::OpFOrdNotEqual:
548
786k
    case spv::Op::OpFUnordNotEqual:
549
795k
    case spv::Op::OpFOrdLessThan:
550
796k
    case spv::Op::OpFUnordLessThan:
551
802k
    case spv::Op::OpFOrdGreaterThan:
552
802k
    case spv::Op::OpFUnordGreaterThan:
553
803k
    case spv::Op::OpFOrdLessThanEqual:
554
806k
    case spv::Op::OpFUnordLessThanEqual:
555
808k
    case spv::Op::OpFOrdGreaterThanEqual:
556
811k
    case spv::Op::OpFUnordGreaterThanEqual:
557
811k
      return true;
558
549k
    default:
559
549k
      return false;
560
1.36M
  }
561
1.36M
}
562
563
14.7M
bool spvOpcodeIsDebug(spv::Op opcode) {
564
14.7M
  switch (opcode) {
565
2.93k
    case spv::Op::OpName:
566
2.98k
    case spv::Op::OpMemberName:
567
2.99k
    case spv::Op::OpSource:
568
2.99k
    case spv::Op::OpSourceContinued:
569
2.99k
    case spv::Op::OpSourceExtension:
570
3.02k
    case spv::Op::OpString:
571
5.20k
    case spv::Op::OpLine:
572
5.20k
    case spv::Op::OpNoLine:
573
5.20k
    case spv::Op::OpModuleProcessed:
574
5.20k
      return true;
575
14.7M
    default:
576
14.7M
      return false;
577
14.7M
  }
578
14.7M
}
579
580
2.93M
bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) {
581
2.93M
  switch (opcode) {
582
0
    case spv::Op::OpPtrEqual:
583
0
    case spv::Op::OpPtrNotEqual:
584
60.2k
    case spv::Op::OpIAdd:
585
287k
    case spv::Op::OpFAdd:
586
295k
    case spv::Op::OpIMul:
587
419k
    case spv::Op::OpFMul:
588
419k
    case spv::Op::OpDot:
589
419k
    case spv::Op::OpIAddCarry:
590
419k
    case spv::Op::OpUMulExtended:
591
419k
    case spv::Op::OpSMulExtended:
592
440k
    case spv::Op::OpBitwiseOr:
593
441k
    case spv::Op::OpBitwiseXor:
594
450k
    case spv::Op::OpBitwiseAnd:
595
450k
    case spv::Op::OpOrdered:
596
450k
    case spv::Op::OpUnordered:
597
450k
    case spv::Op::OpLogicalEqual:
598
450k
    case spv::Op::OpLogicalNotEqual:
599
450k
    case spv::Op::OpLogicalOr:
600
453k
    case spv::Op::OpLogicalAnd:
601
489k
    case spv::Op::OpIEqual:
602
497k
    case spv::Op::OpINotEqual:
603
499k
    case spv::Op::OpFOrdEqual:
604
500k
    case spv::Op::OpFUnordEqual:
605
501k
    case spv::Op::OpFOrdNotEqual:
606
502k
    case spv::Op::OpFUnordNotEqual:
607
502k
      return true;
608
2.43M
    default:
609
2.43M
      return false;
610
2.93M
  }
611
2.93M
}
612
613
0
bool spvOpcodeIsLinearAlgebra(spv::Op opcode) {
614
0
  switch (opcode) {
615
0
    case spv::Op::OpTranspose:
616
0
    case spv::Op::OpVectorTimesScalar:
617
0
    case spv::Op::OpMatrixTimesScalar:
618
0
    case spv::Op::OpVectorTimesMatrix:
619
0
    case spv::Op::OpMatrixTimesVector:
620
0
    case spv::Op::OpMatrixTimesMatrix:
621
0
    case spv::Op::OpOuterProduct:
622
0
    case spv::Op::OpDot:
623
0
      return true;
624
0
    default:
625
0
      return false;
626
0
  }
627
0
}
628
629
0
bool spvOpcodeIsImageSample(const spv::Op opcode) {
630
0
  switch (opcode) {
631
0
    case spv::Op::OpImageSampleImplicitLod:
632
0
    case spv::Op::OpImageSampleExplicitLod:
633
0
    case spv::Op::OpImageSampleDrefImplicitLod:
634
0
    case spv::Op::OpImageSampleDrefExplicitLod:
635
0
    case spv::Op::OpImageSampleProjImplicitLod:
636
0
    case spv::Op::OpImageSampleProjExplicitLod:
637
0
    case spv::Op::OpImageSampleProjDrefImplicitLod:
638
0
    case spv::Op::OpImageSampleProjDrefExplicitLod:
639
0
    case spv::Op::OpImageSparseSampleImplicitLod:
640
0
    case spv::Op::OpImageSparseSampleExplicitLod:
641
0
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
642
0
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
643
0
    case spv::Op::OpImageSampleFootprintNV:
644
0
      return true;
645
0
    default:
646
0
      return false;
647
0
  }
648
0
}
649
650
224M
bool spvIsExtendedInstruction(const spv::Op opcode) {
651
224M
  switch (opcode) {
652
2.08M
    case spv::Op::OpExtInst:
653
2.10M
    case spv::Op::OpExtInstWithForwardRefsKHR:
654
2.10M
      return true;
655
222M
    default:
656
222M
      return false;
657
224M
  }
658
224M
}
659
660
0
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) {
661
0
  switch (opcode) {
662
0
    case spv::Op::OpMemoryBarrier:
663
0
      return {1};
664
0
    case spv::Op::OpAtomicStore:
665
0
    case spv::Op::OpControlBarrier:
666
0
    case spv::Op::OpAtomicFlagClear:
667
0
    case spv::Op::OpMemoryNamedBarrier:
668
0
      return {2};
669
0
    case spv::Op::OpAtomicLoad:
670
0
    case spv::Op::OpAtomicExchange:
671
0
    case spv::Op::OpAtomicIIncrement:
672
0
    case spv::Op::OpAtomicIDecrement:
673
0
    case spv::Op::OpAtomicIAdd:
674
0
    case spv::Op::OpAtomicFAddEXT:
675
0
    case spv::Op::OpAtomicISub:
676
0
    case spv::Op::OpAtomicSMin:
677
0
    case spv::Op::OpAtomicUMin:
678
0
    case spv::Op::OpAtomicSMax:
679
0
    case spv::Op::OpAtomicUMax:
680
0
    case spv::Op::OpAtomicAnd:
681
0
    case spv::Op::OpAtomicOr:
682
0
    case spv::Op::OpAtomicXor:
683
0
    case spv::Op::OpAtomicFlagTestAndSet:
684
0
      return {4};
685
0
    case spv::Op::OpAtomicCompareExchange:
686
0
    case spv::Op::OpAtomicCompareExchangeWeak:
687
0
      return {4, 5};
688
0
    default:
689
0
      return {};
690
0
  }
691
0
}
692
693
0
bool spvOpcodeIsAccessChain(spv::Op opcode) {
694
0
  switch (opcode) {
695
0
    case spv::Op::OpAccessChain:
696
0
    case spv::Op::OpInBoundsAccessChain:
697
0
    case spv::Op::OpPtrAccessChain:
698
0
    case spv::Op::OpInBoundsPtrAccessChain:
699
0
    case spv::Op::OpRawAccessChainNV:
700
0
      return true;
701
0
    default:
702
0
      return false;
703
0
  }
704
0
}
705
706
0
bool spvOpcodeIsBit(spv::Op opcode) {
707
0
  switch (opcode) {
708
0
    case spv::Op::OpShiftRightLogical:
709
0
    case spv::Op::OpShiftRightArithmetic:
710
0
    case spv::Op::OpShiftLeftLogical:
711
0
    case spv::Op::OpBitwiseOr:
712
0
    case spv::Op::OpBitwiseXor:
713
0
    case spv::Op::OpBitwiseAnd:
714
0
    case spv::Op::OpNot:
715
0
    case spv::Op::OpBitReverse:
716
0
    case spv::Op::OpBitCount:
717
0
      return true;
718
0
    default:
719
0
      return false;
720
0
  }
721
0
}
722
723
150k
bool spvOpcodeGeneratesUntypedPointer(spv::Op opcode) {
724
150k
  switch (opcode) {
725
5
    case spv::Op::OpUntypedVariableKHR:
726
19
    case spv::Op::OpUntypedAccessChainKHR:
727
26
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
728
31
    case spv::Op::OpUntypedPtrAccessChainKHR:
729
49
    case spv::Op::OpUntypedInBoundsPtrAccessChainKHR:
730
49
      return true;
731
150k
    default:
732
150k
      return false;
733
150k
  }
734
150k
}