| 594 | } |
| 595 | |
| 596 | spv_result_t ValidateVectorShuffle(ValidationState_t& _, |
| 597 | const Instruction* inst, |
| 598 | uint32_t operand_index = 2) { |
| 599 | auto result_type = _.FindDef(inst->type_id()); |
| 600 | if (!_.IsVectorType(result_type->id())) { |
| 601 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 602 | << "The Result Type of OpVectorShuffle must be" |
| 603 | << " a vector type. Found Op" |
| 604 | << spvOpcodeString(result_type->opcode()) << "."; |
| 605 | } |
| 606 | |
| 607 | // The number of components in Result Type must be the same as the number of |
| 608 | // Component operands. |
| 609 | uint32_t first_literal_index = operand_index + 2; |
| 610 | uint32_t component_count = |
| 611 | static_cast<uint32_t>(inst->operands().size()) - first_literal_index; |
| 612 | auto result_vec_dimension = _.GetDimension(result_type->id()); |
| 613 | if (result_vec_dimension > 0 && component_count != result_vec_dimension) { |
| 614 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 615 | << "OpVectorShuffle component literals count does not match " |
| 616 | "Result Type <id> " |
| 617 | << _.getIdName(result_type->id()) << "s vector component count."; |
| 618 | } |
| 619 | |
| 620 | // Vector 1 and Vector 2 must both have vector types, with the same Component |
| 621 | // Type as Result Type. |
| 622 | auto vec1_type = _.FindDef(_.GetOperandTypeId(inst, operand_index)); |
| 623 | auto vec2_type = _.FindDef(_.GetOperandTypeId(inst, operand_index + 1)); |
| 624 | if (!vec1_type || !_.IsVectorType(vec1_type->id())) { |
| 625 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 626 | << "The type of Vector 1 must be a vector type."; |
| 627 | } |
| 628 | if (!vec2_type || !_.IsVectorType(vec2_type->id())) { |
| 629 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 630 | << "The type of Vector 2 must be a vector type."; |
| 631 | } |
| 632 | |
| 633 | uint32_t result_component_type = result_type->GetOperandAs<uint32_t>(1); |
| 634 | if (vec1_type->GetOperandAs<uint32_t>(1) != result_component_type) { |
| 635 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 636 | << "The Component Type of Vector 1 must be the same as ResultType."; |
| 637 | } |
| 638 | if (vec2_type->GetOperandAs<uint32_t>(1) != result_component_type) { |
| 639 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 640 | << "The Component Type of Vector 2 must be the same as ResultType."; |
| 641 | } |
| 642 | |
| 643 | // All Component literals must either be FFFFFFFF or in [0, N - 1]. |
| 644 | uint32_t vec1_component_count = vec1_type->GetOperandAs<uint32_t>(2); |
| 645 | uint32_t vec2_component_count = vec2_type->GetOperandAs<uint32_t>(2); |
| 646 | uint32_t N = vec1_component_count + vec2_component_count; |
| 647 | for (size_t i = first_literal_index; i < inst->operands().size(); ++i) { |
| 648 | uint32_t literal = inst->GetOperandAs<uint32_t>(i); |
| 649 | if (literal != 0xFFFFFFFF && literal >= N) { |
| 650 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 651 | << "Component index " << literal << " is out of bounds for " |
| 652 | << "combined (Vector1 + Vector2) size of " << N << "."; |
| 653 | } |
no test coverage detected