Validate OpenCL rules for ImageRead and OpImageSampleExplicitLod (#2643)

Fixes #2594.

Signed-off-by: Kevin Petit <kevin.petit@arm.com>
This commit is contained in:
Kévin Petit 2019-05-31 15:05:34 +01:00 committed by alan-baker
parent 209ff0ce90
commit f99d7ad5c0
2 changed files with 103 additions and 0 deletions

View File

@ -1114,6 +1114,17 @@ spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
}
const uint32_t mask = inst->word(5);
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (opcode == SpvOpImageSampleExplicitLod) {
if (mask & SpvImageOperandsConstOffsetMask) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "ConstOffset image operand not allowed "
<< "in the OpenCL environment.";
}
}
}
if (spv_result_t result =
ValidateImageOperands(_, inst, info, mask, /* word_index = */ 6))
return result;
@ -1440,6 +1451,15 @@ spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
if (inst->words().size() <= 5) return SPV_SUCCESS;
const uint32_t mask = inst->word(5);
if (spvIsOpenCLEnv(_.context()->target_env)) {
if (mask & SpvImageOperandsConstOffsetMask) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "ConstOffset image operand not allowed "
<< "in the OpenCL environment.";
}
}
if (spv_result_t result =
ValidateImageOperands(_, inst, info, mask, /* word_index = */ 6))
return result;

View File

@ -184,6 +184,89 @@ TEST_F(ValidateOpenCL, ImageWriteWithOptionalImageOperandsBad) {
"\n OpImageWrite %15 %13 %14 ConstOffset %13\n"));
}
TEST_F(ValidateOpenCL, ImageReadWithConstOffsetBad) {
std::string spirv = R"(
OpCapability Addresses
OpCapability Kernel
OpCapability ImageBasic
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %5 "image_kernel"
OpName %img "img"
OpName %coord "coord"
OpName %call "call"
%uint = OpTypeInt 32 0
%uint_7 = OpConstant %uint 7
%uint_3 = OpConstant %uint 3
%void = OpTypeVoid
%3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
%4 = OpTypeFunction %void %3
%v4uint = OpTypeVector %uint 4
%v2uint = OpTypeVector %uint 2
%coord = OpConstantComposite %v2uint %uint_7 %uint_3
%5 = OpFunction %void None %4
%img = OpFunctionParameter %3
%entry = OpLabel
%call = OpImageRead %v4uint %img %coord ConstOffset %coord
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"ConstOffset image operand not allowed in the OpenCL environment."
"\n %call = OpImageRead %v4uint %img %coord ConstOffset %coord\n"));
}
TEST_F(ValidateOpenCL, ImageSampleExplicitLodWithConstOffsetBad) {
std::string spirv = R"(
OpCapability Addresses
OpCapability Kernel
OpCapability ImageBasic
OpCapability LiteralSampler
OpMemoryModel Physical64 OpenCL
OpEntryPoint Kernel %5 "image_kernel"
OpName %img "img"
OpName %coord "coord"
OpName %call "call"
%uint = OpTypeInt 32 0
%uint_7 = OpConstant %uint 7
%uint_3 = OpConstant %uint 3
%void = OpTypeVoid
%3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
%4 = OpTypeFunction %void %3
%8 = OpTypeSampler
%10 = OpTypeSampledImage %3
%v4uint = OpTypeVector %uint 4
%v2uint = OpTypeVector %uint 2
%float = OpTypeFloat 32
%9 = OpConstantSampler %8 None 0 Nearest
%coord = OpConstantComposite %v2uint %uint_7 %uint_3
%float_0 = OpConstant %float 0
%5 = OpFunction %void None %4
%6 = OpFunctionParameter %3
%entry = OpLabel
%img = OpSampledImage %10 %6 %9
%call = OpImageSampleExplicitLod %v4uint %img %coord
Lod|ConstOffset %float_0 %coord
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"ConstOffset image operand not allowed in the OpenCL environment."
"\n %call = OpImageSampleExplicitLod %v4uint %img "
"%coord Lod|ConstOffset %float_0 %coord\n"));
}
} // namespace
} // namespace val
} // namespace spvtools