MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / ValidateLoopMerge

Function ValidateLoopMerge

source/val/validate_cfg.cpp:279–353  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

277}
278
279spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) {
280 const auto merge_id = inst->GetOperandAs<uint32_t>(0);
281 const auto merge = _.FindDef(merge_id);
282 if (!merge || merge->opcode() != spv::Op::OpLabel) {
283 return _.diag(SPV_ERROR_INVALID_ID, inst)
284 << "Merge Block " << _.getIdName(merge_id) << " must be an OpLabel";
285 }
286 if (merge_id == inst->block()->id()) {
287 return _.diag(SPV_ERROR_INVALID_ID, inst)
288 << "Merge Block may not be the block containing the OpLoopMerge\n";
289 }
290
291 const auto continue_id = inst->GetOperandAs<uint32_t>(1);
292 const auto continue_target = _.FindDef(continue_id);
293 if (!continue_target || continue_target->opcode() != spv::Op::OpLabel) {
294 return _.diag(SPV_ERROR_INVALID_ID, inst)
295 << "Continue Target " << _.getIdName(continue_id)
296 << " must be an OpLabel";
297 }
298
299 if (merge_id == continue_id) {
300 return _.diag(SPV_ERROR_INVALID_ID, inst)
301 << "Merge Block and Continue Target must be different ids";
302 }
303
304 const auto loop_control = inst->GetOperandAs<spv::LoopControlShift>(2);
305 if ((loop_control >> spv::LoopControlShift::Unroll) & 0x1 &&
306 (loop_control >> spv::LoopControlShift::DontUnroll) & 0x1) {
307 return _.diag(SPV_ERROR_INVALID_DATA, inst)
308 << "Unroll and DontUnroll loop controls must not both be specified";
309 }
310 if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 &&
311 (loop_control >> spv::LoopControlShift::PeelCount) & 0x1) {
312 return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PeelCount and DontUnroll "
313 "loop controls must not "
314 "both be specified";
315 }
316 if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 &&
317 (loop_control >> spv::LoopControlShift::PartialCount) & 0x1) {
318 return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PartialCount and "
319 "DontUnroll loop controls "
320 "must not both be specified";
321 }
322
323 uint32_t operand = 3;
324 if ((loop_control >> spv::LoopControlShift::DependencyLength) & 0x1) {
325 ++operand;
326 }
327 if ((loop_control >> spv::LoopControlShift::MinIterations) & 0x1) {
328 ++operand;
329 }
330 if ((loop_control >> spv::LoopControlShift::MaxIterations) & 0x1) {
331 ++operand;
332 }
333 if ((loop_control >> spv::LoopControlShift::IterationMultiple) & 0x1) {
334 if (inst->operands().size() < operand ||
335 inst->GetOperandAs<uint32_t>(operand) == 0) {
336 return _.diag(SPV_ERROR_INVALID_DATA, inst) << "IterationMultiple loop "

Callers 1

ControlFlowPassFunction · 0.85

Calls 8

FindDefMethod · 0.80
diagMethod · 0.80
getIdNameMethod · 0.80
operandsMethod · 0.80
opcodeMethod · 0.45
idMethod · 0.45
blockMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected