| 641 | } |
| 642 | |
| 643 | spv_result_t ValidateBitcast(ValidationState_t& _, const Instruction* inst, |
| 644 | uint32_t operand_index = 2) { |
| 645 | const spv::Op opcode = inst->opcode(); |
| 646 | const uint32_t result_type = inst->type_id(); |
| 647 | const uint32_t input_type = _.GetOperandTypeId(inst, operand_index); |
| 648 | if (!input_type) |
| 649 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 650 | << "Expected input to have a type: " << spvOpcodeString(opcode); |
| 651 | |
| 652 | const bool result_is_pointer = _.IsPointerType(result_type); |
| 653 | const bool result_is_int_scalar = _.IsIntScalarType(result_type); |
| 654 | const bool input_is_pointer = _.IsPointerType(input_type); |
| 655 | const bool input_is_int_scalar = _.IsIntScalarType(input_type); |
| 656 | |
| 657 | const bool result_is_coopmat = _.IsCooperativeMatrixType(result_type); |
| 658 | const bool input_is_coopmat = _.IsCooperativeMatrixType(input_type); |
| 659 | const bool result_is_coopvec = _.IsCooperativeVectorNVType(result_type); |
| 660 | const bool input_is_coopvec = _.IsCooperativeVectorNVType(input_type); |
| 661 | |
| 662 | if (!result_is_pointer && !result_is_int_scalar && !result_is_coopmat && |
| 663 | !result_is_coopvec && !_.IsIntVectorType(result_type) && |
| 664 | !_.IsFloatScalarType(result_type) && !_.IsFloatVectorType(result_type)) |
| 665 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 666 | << "Expected Result Type to be a pointer or int or float vector " |
| 667 | << "or scalar type: " << spvOpcodeString(opcode); |
| 668 | |
| 669 | if (!input_is_pointer && !input_is_int_scalar && !input_is_coopmat && |
| 670 | !input_is_coopvec && !_.IsIntVectorType(input_type) && |
| 671 | !_.IsFloatScalarType(input_type) && !_.IsFloatVectorType(input_type)) |
| 672 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 673 | << "Expected input to be a pointer or int or float vector " |
| 674 | << "or scalar: " << spvOpcodeString(opcode); |
| 675 | |
| 676 | // NV_cooperative_vector doesn't allow bitcasting between vec<->coopvec, |
| 677 | // but long_vector does. |
| 678 | if (result_is_coopvec != input_is_coopvec && |
| 679 | !_.HasCapability(spv::Capability::LongVectorEXT)) |
| 680 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 681 | << "Cooperative vector can only be cast to another cooperative " |
| 682 | << "vector: " << spvOpcodeString(opcode); |
| 683 | |
| 684 | if (result_is_coopmat != input_is_coopmat) |
| 685 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 686 | << "Cooperative matrix can only be cast to another cooperative " |
| 687 | << "matrix: " << spvOpcodeString(opcode); |
| 688 | |
| 689 | if (result_is_coopvec && input_is_coopvec && |
| 690 | !_.HasCapability(spv::Capability::LongVectorEXT)) { |
| 691 | spv_result_t ret = |
| 692 | _.CooperativeVectorDimensionsMatch(inst, result_type, input_type); |
| 693 | if (ret != SPV_SUCCESS) return ret; |
| 694 | } |
| 695 | |
| 696 | if (result_is_coopmat) { |
| 697 | spv_result_t ret = |
| 698 | _.CooperativeMatrixShapesMatch(inst, result_type, input_type, false); |
| 699 | if (ret != SPV_SUCCESS) return ret; |
| 700 | } |
no test coverage detected