| 2999 | } |
| 3000 | |
| 3001 | spv_result_t ValidateCooperativeVectorPointer(ValidationState_t& _, |
| 3002 | const Instruction* inst, |
| 3003 | const char* opname, |
| 3004 | uint32_t pointer_index) { |
| 3005 | const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index); |
| 3006 | const auto pointer = _.FindDef(pointer_id); |
| 3007 | if (!pointer || |
| 3008 | ((_.addressing_model() == spv::AddressingModel::Logical) && |
| 3009 | ((!_.features().variable_pointers && |
| 3010 | !spvOpcodeReturnsLogicalPointer(pointer->opcode())) || |
| 3011 | (_.features().variable_pointers && |
| 3012 | !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) { |
| 3013 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 3014 | << opname << " Pointer <id> " << _.getIdName(pointer_id) |
| 3015 | << " is not a logical pointer."; |
| 3016 | } |
| 3017 | |
| 3018 | const auto pointer_type_id = pointer->type_id(); |
| 3019 | const auto pointer_type = _.FindDef(pointer_type_id); |
| 3020 | if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) { |
| 3021 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 3022 | << opname << " type for pointer <id> " << _.getIdName(pointer_id) |
| 3023 | << " is not a pointer type."; |
| 3024 | } |
| 3025 | |
| 3026 | const auto storage_class_index = 1u; |
| 3027 | const auto storage_class = |
| 3028 | pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index); |
| 3029 | |
| 3030 | if (storage_class != spv::StorageClass::Workgroup && |
| 3031 | storage_class != spv::StorageClass::StorageBuffer && |
| 3032 | storage_class != spv::StorageClass::PhysicalStorageBuffer) { |
| 3033 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 3034 | << opname << " storage class for pointer type <id> " |
| 3035 | << _.getIdName(pointer_type_id) |
| 3036 | << " is not Workgroup or StorageBuffer."; |
| 3037 | } |
| 3038 | |
| 3039 | const auto pointee_id = pointer_type->GetOperandAs<uint32_t>(2); |
| 3040 | const auto pointee_type = _.FindDef(pointee_id); |
| 3041 | if (!pointee_type || |
| 3042 | (pointee_type->opcode() != spv::Op::OpTypeArray && |
| 3043 | pointee_type->opcode() != spv::Op::OpTypeRuntimeArray)) { |
| 3044 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 3045 | << opname << " Pointer <id> " << _.getIdName(pointer->id()) |
| 3046 | << "s Type must be an array type."; |
| 3047 | } |
| 3048 | |
| 3049 | const auto array_elem_type_id = pointee_type->GetOperandAs<uint32_t>(1); |
| 3050 | auto array_elem_type = _.FindDef(array_elem_type_id); |
| 3051 | if (!array_elem_type || !(_.IsIntScalarOrVectorType(array_elem_type_id) || |
| 3052 | _.IsFloatScalarOrVectorType(array_elem_type_id))) { |
| 3053 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 3054 | << opname << " Pointer <id> " << _.getIdName(pointer->id()) |
| 3055 | << "s Type must be an array of scalar or vector type."; |
| 3056 | } |
| 3057 | |
| 3058 | return SPV_SUCCESS; |
no test coverage detected