@@ -115,6 +115,55 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) {
115
115
return SPV_SUCCESS;
116
116
}
117
117
118
+ bool InstructionCanHaveTypeOperand (const Instruction* inst) {
119
+ static std::unordered_set<spv::Op> instruction_allow_set{
120
+ spv::Op::OpSizeOf,
121
+ spv::Op::OpCooperativeMatrixLengthNV,
122
+ spv::Op::OpCooperativeMatrixLengthKHR,
123
+ spv::Op::OpUntypedArrayLengthKHR,
124
+ spv::Op::OpFunction,
125
+ };
126
+ const auto opcode = inst->opcode ();
127
+ bool type_instruction = spvOpcodeGeneratesType (opcode);
128
+ bool debug_instruction = spvOpcodeIsDebug (opcode) || inst->IsDebugInfo ();
129
+ bool coop_matrix_spec_constant_op_length =
130
+ (opcode == spv::Op::OpSpecConstantOp) &&
131
+ (spv::Op (inst->word (3 )) == spv::Op::OpCooperativeMatrixLengthNV ||
132
+ spv::Op (inst->word (3 )) == spv::Op::OpCooperativeMatrixLengthKHR);
133
+ return type_instruction || debug_instruction || inst->IsNonSemantic () ||
134
+ spvOpcodeIsDecoration (opcode) || instruction_allow_set.count (opcode) ||
135
+ spvOpcodeGeneratesUntypedPointer (opcode) ||
136
+ coop_matrix_spec_constant_op_length;
137
+ }
138
+
139
+ bool InstructionRequiresTypeOperand (const Instruction* inst) {
140
+ static std::unordered_set<spv::Op> instruction_deny_set{
141
+ spv::Op::OpExtInst,
142
+ spv::Op::OpExtInstWithForwardRefsKHR,
143
+ spv::Op::OpExtInstImport,
144
+ spv::Op::OpSelectionMerge,
145
+ spv::Op::OpLoopMerge,
146
+ spv::Op::OpFunction,
147
+ spv::Op::OpSizeOf,
148
+ spv::Op::OpCooperativeMatrixLengthNV,
149
+ spv::Op::OpCooperativeMatrixLengthKHR,
150
+ spv::Op::OpPhi,
151
+ spv::Op::OpUntypedArrayLengthKHR,
152
+ };
153
+ const auto opcode = inst->opcode ();
154
+ bool debug_instruction = spvOpcodeIsDebug (opcode) || inst->IsDebugInfo ();
155
+ bool coop_matrix_spec_constant_op_length =
156
+ opcode == spv::Op::OpSpecConstantOp &&
157
+ (spv::Op (inst->word (3 )) == spv::Op::OpCooperativeMatrixLengthNV ||
158
+ spv::Op (inst->word (3 )) == spv::Op::OpCooperativeMatrixLengthKHR);
159
+
160
+ return !debug_instruction && !inst->IsNonSemantic () &&
161
+ !spvOpcodeIsDecoration (opcode) && !spvOpcodeIsBranch (opcode) &&
162
+ !instruction_deny_set.count (opcode) &&
163
+ !spvOpcodeGeneratesUntypedPointer (opcode) &&
164
+ !coop_matrix_spec_constant_op_length;
165
+ }
166
+
118
167
// Performs SSA validation on the IDs of an instruction. The
119
168
// can_have_forward_declared_ids functor should return true if the
120
169
// instruction operand's ID can be forward referenced.
@@ -158,44 +207,14 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
158
207
case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
159
208
case SPV_OPERAND_TYPE_SCOPE_ID:
160
209
if (const auto def = _.FindDef (operand_word)) {
161
- const auto opcode = inst->opcode ();
162
210
if (spvOpcodeGeneratesType (def->opcode ()) &&
163
- !spvOpcodeGeneratesType (opcode) && !spvOpcodeIsDebug (opcode) &&
164
- !inst->IsDebugInfo () && !inst->IsNonSemantic () &&
165
- !spvOpcodeIsDecoration (opcode) && opcode != spv::Op::OpFunction &&
166
- opcode != spv::Op::OpSizeOf &&
167
- opcode != spv::Op::OpCooperativeMatrixLengthNV &&
168
- opcode != spv::Op::OpCooperativeMatrixLengthKHR &&
169
- !spvOpcodeGeneratesUntypedPointer (opcode) &&
170
- opcode != spv::Op::OpUntypedArrayLengthKHR &&
171
- !(opcode == spv::Op::OpSpecConstantOp &&
172
- (spv::Op (inst->word (3 )) ==
173
- spv::Op::OpCooperativeMatrixLengthNV ||
174
- spv::Op (inst->word (3 )) ==
175
- spv::Op::OpCooperativeMatrixLengthKHR))) {
211
+ !InstructionCanHaveTypeOperand (inst)) {
176
212
return _.diag (SPV_ERROR_INVALID_ID, inst)
177
213
<< " Operand " << _.getIdName (operand_word)
178
214
<< " cannot be a type" ;
179
- } else if (def->type_id () == 0 && !spvOpcodeGeneratesType (opcode) &&
180
- !spvOpcodeIsDebug (opcode) && !inst->IsDebugInfo () &&
181
- !inst->IsNonSemantic () && !spvOpcodeIsDecoration (opcode) &&
182
- !spvOpcodeIsBranch (opcode) && opcode != spv::Op::OpPhi &&
183
- opcode != spv::Op::OpExtInst &&
184
- opcode != spv::Op::OpExtInstWithForwardRefsKHR &&
185
- opcode != spv::Op::OpExtInstImport &&
186
- opcode != spv::Op::OpSelectionMerge &&
187
- opcode != spv::Op::OpLoopMerge &&
188
- opcode != spv::Op::OpFunction &&
189
- opcode != spv::Op::OpSizeOf &&
190
- opcode != spv::Op::OpCooperativeMatrixLengthNV &&
191
- opcode != spv::Op::OpCooperativeMatrixLengthKHR &&
192
- !spvOpcodeGeneratesUntypedPointer (opcode) &&
193
- opcode != spv::Op::OpUntypedArrayLengthKHR &&
194
- !(opcode == spv::Op::OpSpecConstantOp &&
195
- (spv::Op (inst->word (3 )) ==
196
- spv::Op::OpCooperativeMatrixLengthNV ||
197
- spv::Op (inst->word (3 )) ==
198
- spv::Op::OpCooperativeMatrixLengthKHR))) {
215
+ } else if (def->type_id () == 0 &&
216
+ !spvOpcodeGeneratesType (def->opcode ()) &&
217
+ InstructionRequiresTypeOperand (inst)) {
199
218
return _.diag (SPV_ERROR_INVALID_ID, inst)
200
219
<< " Operand " << _.getIdName (operand_word)
201
220
<< " requires a type" ;
0 commit comments