Skip to content

Commit dab29fb

Browse files
authored
spirv-val: tidy up validation of type constraints for IDs (KhronosGroup#6185)
This makes the overall logic a bit easier to follow and modify in my opinion. It also makes its shortcomings a bit more apparent. Change-Id: Iad296cf5b0a27a135073710edc60cd5bed8ce810 Signed-off-by: Kevin Petit <[email protected]>
1 parent dec2864 commit dab29fb

File tree

1 file changed

+53
-34
lines changed

1 file changed

+53
-34
lines changed

source/val/validate_id.cpp

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,55 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) {
115115
return SPV_SUCCESS;
116116
}
117117

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+
118167
// Performs SSA validation on the IDs of an instruction. The
119168
// can_have_forward_declared_ids functor should return true if the
120169
// instruction operand's ID can be forward referenced.
@@ -158,44 +207,14 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
158207
case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
159208
case SPV_OPERAND_TYPE_SCOPE_ID:
160209
if (const auto def = _.FindDef(operand_word)) {
161-
const auto opcode = inst->opcode();
162210
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)) {
176212
return _.diag(SPV_ERROR_INVALID_ID, inst)
177213
<< "Operand " << _.getIdName(operand_word)
178214
<< " 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)) {
199218
return _.diag(SPV_ERROR_INVALID_ID, inst)
200219
<< "Operand " << _.getIdName(operand_word)
201220
<< " requires a type";

0 commit comments

Comments
 (0)