Update remquo validation to match the OpenCL Extended Instruction Set Specification (#2791)

This commit is contained in:
Toomas Remmelg 2019-08-15 14:38:37 +01:00 committed by alan-baker
parent dac9210dcb
commit 7b4e5bd5ec
2 changed files with 94 additions and 67 deletions

View File

@ -923,7 +923,58 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
case OpenCLLIB::Fract: case OpenCLLIB::Fract:
case OpenCLLIB::Modf: case OpenCLLIB::Modf:
case OpenCLLIB::Sincos: case OpenCLLIB::Sincos: {
if (!_.IsFloatScalarOrVectorType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be a float scalar or vector type";
}
const uint32_t num_components = _.GetDimension(result_type);
if (num_components > 4 && num_components != 8 && num_components != 16) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be a scalar or a vector with 2, "
"3, 4, 8 or 16 components";
}
const uint32_t x_type = _.GetOperandTypeId(inst, 4);
if (result_type != x_type) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected type of operand X to be equal to Result Type";
}
const uint32_t p_type = _.GetOperandTypeId(inst, 5);
uint32_t p_storage_class = 0;
uint32_t p_data_type = 0;
if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected the last operand to be a pointer";
}
if (p_storage_class != SpvStorageClassGeneric &&
p_storage_class != SpvStorageClassCrossWorkgroup &&
p_storage_class != SpvStorageClassWorkgroup &&
p_storage_class != SpvStorageClassFunction) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected storage class of the pointer to be Generic, "
"CrossWorkgroup, Workgroup or Function";
}
if (result_type != p_data_type) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected data type of the pointer to be equal to Result "
"Type";
}
break;
}
case OpenCLLIB::Frexp:
case OpenCLLIB::Lgamma_r:
case OpenCLLIB::Remquo: { case OpenCLLIB::Remquo: {
if (!_.IsFloatScalarOrVectorType(result_type)) { if (!_.IsFloatScalarOrVectorType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)
@ -975,57 +1026,6 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
"CrossWorkgroup, Workgroup or Function"; "CrossWorkgroup, Workgroup or Function";
} }
if (result_type != p_data_type) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected data type of the pointer to be equal to Result "
"Type";
}
break;
}
case OpenCLLIB::Frexp:
case OpenCLLIB::Lgamma_r: {
if (!_.IsFloatScalarOrVectorType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be a float scalar or vector type";
}
const uint32_t num_components = _.GetDimension(result_type);
if (num_components > 4 && num_components != 8 && num_components != 16) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected Result Type to be a scalar or a vector with 2, "
"3, 4, 8 or 16 components";
}
const uint32_t x_type = _.GetOperandTypeId(inst, 4);
if (result_type != x_type) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected type of operand X to be equal to Result Type";
}
const uint32_t p_type = _.GetOperandTypeId(inst, 5);
uint32_t p_storage_class = 0;
uint32_t p_data_type = 0;
if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected the last operand to be a pointer";
}
if (p_storage_class != SpvStorageClassGeneric &&
p_storage_class != SpvStorageClassCrossWorkgroup &&
p_storage_class != SpvStorageClassWorkgroup &&
p_storage_class != SpvStorageClassFunction) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected storage class of the pointer to be Generic, "
"CrossWorkgroup, Workgroup or Function";
}
if (!_.IsIntScalarOrVectorType(p_data_type) || if (!_.IsIntScalarOrVectorType(p_data_type) ||
_.GetBitWidth(p_data_type) != 32) { _.GetBitWidth(p_data_type) != 32) {
return _.diag(SPV_ERROR_INVALID_DATA, inst) return _.diag(SPV_ERROR_INVALID_DATA, inst)

View File

@ -5315,10 +5315,10 @@ INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) { TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
const std::string body = R"( const std::string body = R"(
%var_f32 = OpVariable %f32_ptr_function Function %var_u32 = OpVariable %u32_ptr_function Function
%var_f32vec2 = OpVariable %f32vec2_ptr_function Function %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
%val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
%val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_f32vec2 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
)"; )";
CompileSuccessfully(GenerateKernelCode(body)); CompileSuccessfully(GenerateKernelCode(body));
@ -5327,8 +5327,8 @@ TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) { TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
const std::string body = R"( const std::string body = R"(
%var_f32 = OpVariable %f32_ptr_function Function %var_u32 = OpVariable %u32_ptr_function Function
%val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_f32 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
)"; )";
CompileSuccessfully(GenerateKernelCode(body)); CompileSuccessfully(GenerateKernelCode(body));
@ -5341,8 +5341,8 @@ TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) { TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
const std::string body = R"( const std::string body = R"(
%var_f32 = OpVariable %f32_ptr_function Function %var_u32 = OpVariable %f32_ptr_function Function
%val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_f32 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
)"; )";
CompileSuccessfully(GenerateKernelCode(body)); CompileSuccessfully(GenerateKernelCode(body));
@ -5355,8 +5355,8 @@ TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) { TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
const std::string body = R"( const std::string body = R"(
%var_f32 = OpVariable %f32_ptr_function Function %var_u32 = OpVariable %f32_ptr_function Function
%val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_f32 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
)"; )";
CompileSuccessfully(GenerateKernelCode(body)); CompileSuccessfully(GenerateKernelCode(body));
@ -5395,17 +5395,44 @@ TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) { TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
const std::string body = R"( const std::string body = R"(
%var_u32 = OpVariable %u32_ptr_function Function %var_f32 = OpVariable %f32_ptr_function Function
%val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
)";
CompileSuccessfully(GenerateKernelCode(body));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("OpenCL.std remquo: "
"expected data type of the pointer to be a 32-bit int "
"scalar or vector type"));
}
TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
const std::string body = R"(
%var_u64 = OpVariable %u64_ptr_function Function
%val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
)";
CompileSuccessfully(GenerateKernelCode(body));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("OpenCL.std remquo: "
"expected data type of the pointer to be a 32-bit int "
"scalar or vector type"));
}
TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
const std::string body = R"(
%var_u32vec2 = OpVariable %u32vec2_ptr_function Function
%val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
)"; )";
CompileSuccessfully(GenerateKernelCode(body)); CompileSuccessfully(GenerateKernelCode(body));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions()); ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT( EXPECT_THAT(
getDiagnosticString(), getDiagnosticString(),
HasSubstr( HasSubstr("OpenCL.std remquo: "
"OpenCL.std remquo: " "expected data type of the pointer to have the same number "
"expected data type of the pointer to be equal to Result Type")); "of components as Result Type"));
} }
TEST_P(ValidateOpenCLStdFrexpLike, Success) { TEST_P(ValidateOpenCLStdFrexpLike, Success) {