| 822 | } |
| 823 | |
| 824 | spv_result_t ValidateBitCastArray(ValidationState_t& _, |
| 825 | const Instruction* inst) { |
| 826 | const spv::Op opcode = inst->opcode(); |
| 827 | const uint32_t result_type = inst->type_id(); |
| 828 | const auto result_type_inst = _.FindDef(result_type); |
| 829 | const auto source = _.FindDef(inst->GetOperandAs<uint32_t>(2u)); |
| 830 | const auto source_type_inst = _.FindDef(source->type_id()); |
| 831 | |
| 832 | // Are the input and the result arrays? |
| 833 | if (result_type_inst->opcode() != spv::Op::OpTypeArray || |
| 834 | source_type_inst->opcode() != spv::Op::OpTypeArray) { |
| 835 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 836 | << "Opcode " << spvOpcodeString(opcode) |
| 837 | << " requires OpTypeArray operands for the input and the " |
| 838 | "result."; |
| 839 | } |
| 840 | |
| 841 | const auto source_elt_type = _.GetComponentType(source_type_inst->id()); |
| 842 | const auto result_elt_type = _.GetComponentType(result_type_inst->id()); |
| 843 | |
| 844 | if (!_.IsIntNOrFP32OrFP16<32>(source_elt_type)) { |
| 845 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 846 | << "Opcode " << spvOpcodeString(opcode) |
| 847 | << " requires the source element type be one of 32-bit " |
| 848 | "OpTypeInt " |
| 849 | "(signed/unsigned), 32-bit OpTypeFloat and 16-bit " |
| 850 | "OpTypeFloat"; |
| 851 | } |
| 852 | |
| 853 | if (!_.IsIntNOrFP32OrFP16<32>(result_elt_type)) { |
| 854 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 855 | << "Opcode " << spvOpcodeString(opcode) |
| 856 | << " requires the result element type be one of 32-bit " |
| 857 | "OpTypeInt " |
| 858 | "(signed/unsigned), 32-bit OpTypeFloat and 16-bit " |
| 859 | "OpTypeFloat"; |
| 860 | } |
| 861 | |
| 862 | unsigned src_arr_len_id = source_type_inst->GetOperandAs<unsigned>(2u); |
| 863 | unsigned res_arr_len_id = result_type_inst->GetOperandAs<unsigned>(2u); |
| 864 | |
| 865 | // Are the input and result element types compatible? |
| 866 | unsigned src_arr_len = UINT_MAX, res_arr_len = UINT_MAX; |
| 867 | bool src_arr_len_status = |
| 868 | _.GetConstantValueAs<unsigned>(src_arr_len_id, src_arr_len); |
| 869 | bool res_arr_len_status = |
| 870 | _.GetConstantValueAs<unsigned>(res_arr_len_id, res_arr_len); |
| 871 | |
| 872 | bool is_src_arr_len_spec_const = |
| 873 | spvOpcodeIsSpecConstant(_.FindDef(src_arr_len_id)->opcode()); |
| 874 | bool is_res_arr_len_spec_const = |
| 875 | spvOpcodeIsSpecConstant(_.FindDef(res_arr_len_id)->opcode()); |
| 876 | |
| 877 | unsigned source_bitlen = _.GetBitWidth(source_elt_type) * src_arr_len; |
| 878 | unsigned result_bitlen = _.GetBitWidth(result_elt_type) * res_arr_len; |
| 879 | if (!is_src_arr_len_spec_const && !is_res_arr_len_spec_const && |
| 880 | (!src_arr_len_status || !res_arr_len_status || |
| 881 | source_bitlen != result_bitlen)) { |
no test coverage detected