Validate component literals for OpVectorShuffle in WebGPU environment (#2077)

Validate component literals for OpVectorShuffle in WebGPU environment

Fixes #2072
This commit is contained in:
Ryan Harrison 2018-11-19 14:32:18 -05:00 committed by GitHub
parent d652ed3029
commit 8cd2a9d187
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 0 deletions

View File

@ -220,3 +220,31 @@ bool spvIsOpenCLEnv(spv_target_env env) {
}
return false;
}
bool spvIsWebGPUEnv(spv_target_env env) {
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
case SPV_ENV_VULKAN_1_0:
case SPV_ENV_UNIVERSAL_1_1:
case SPV_ENV_OPENGL_4_0:
case SPV_ENV_OPENGL_4_1:
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_UNIVERSAL_1_3:
case SPV_ENV_VULKAN_1_1:
case SPV_ENV_OPENCL_1_2:
case SPV_ENV_OPENCL_EMBEDDED_1_2:
case SPV_ENV_OPENCL_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_0:
case SPV_ENV_OPENCL_EMBEDDED_2_1:
case SPV_ENV_OPENCL_EMBEDDED_2_2:
case SPV_ENV_OPENCL_2_1:
case SPV_ENV_OPENCL_2_2:
return false;
case SPV_ENV_WEBGPU_0:
return true;
}
return false;
}

View File

@ -27,6 +27,9 @@ bool spvIsVulkanEnv(spv_target_env env);
// Returns true if |env| is an OPENCL environment, false otherwise.
bool spvIsOpenCLEnv(spv_target_env env);
// Returns true if |env| is an WEBGPU environment, false otherwise.
bool spvIsWebGPUEnv(spv_target_env env);
// Returns the version number for the given SPIR-V target environment.
uint32_t spvVersionForTargetEnv(spv_target_env env);

View File

@ -18,6 +18,7 @@
#include "source/diagnostic.h"
#include "source/opcode.h"
#include "source/spirv_target_env.h"
#include "source/val/instruction.h"
#include "source/val/validation_state.h"
@ -464,10 +465,12 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _,
}
// All Component literals must either be FFFFFFFF or in [0, N - 1].
// For WebGPU specifically, Component literals cannot be FFFFFFFF.
auto vector1ComponentCount = vector1Type->GetOperandAs<uint32_t>(2);
auto vector2ComponentCount = vector2Type->GetOperandAs<uint32_t>(2);
auto N = vector1ComponentCount + vector2ComponentCount;
auto firstLiteralIndex = 4;
const auto is_webgpu_env = spvIsWebGPUEnv(_.context()->target_env);
for (size_t i = firstLiteralIndex; i < inst->operands().size(); ++i) {
auto literal = inst->GetOperandAs<uint32_t>(i);
if (literal != 0xFFFFFFFF && literal >= N) {
@ -475,6 +478,12 @@ spv_result_t ValidateVectorShuffle(ValidationState_t& _,
<< "Component index " << literal << " is out of bounds for "
<< "combined (Vector1 + Vector2) size of " << N << ".";
}
if (is_webgpu_env && literal == 0xFFFFFFFF) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Component literal at operand " << i - firstLiteralIndex
<< " cannot be 0xFFFFFFFF in WebGPU execution environment.";
}
}
return SPV_SUCCESS;

View File

@ -4185,6 +4185,37 @@ TEST_F(ValidateIdWithMessage, OpVectorShuffleLiterals) {
"size of 5."));
}
TEST_F(ValidateIdWithMessage, WebGPUOpVectorShuffle0xFFFFFFFFLiteralBad) {
std::string spirv = R"(
OpCapability Shader
OpMemoryModel Logical GLSL450
%float = OpTypeFloat 32
%vec2 = OpTypeVector %float 2
%vec3 = OpTypeVector %float 3
%vec4 = OpTypeVector %float 4
%ptr_vec2 = OpTypePointer Function %vec2
%ptr_vec3 = OpTypePointer Function %vec3
%float_1 = OpConstant %float 1
%float_2 = OpConstant %float 2
%1 = OpConstantComposite %vec2 %float_2 %float_1
%2 = OpConstantComposite %vec3 %float_1 %float_2 %float_2
%3 = OpTypeFunction %vec4
%4 = OpFunction %vec4 None %3
%5 = OpLabel
%var = OpVariable %ptr_vec2 Function %1
%var2 = OpVariable %ptr_vec3 Function %2
%6 = OpLoad %vec2 %var
%7 = OpLoad %vec3 %var2
%8 = OpVectorShuffle %vec4 %6 %7 4 3 1 0xffffffff
OpReturnValue %8
OpFunctionEnd)";
CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Component literal at operand 3 cannot be 0xFFFFFFFF in"
" WebGPU execution environment."));
}
// TODO: OpCompositeConstruct
// TODO: OpCompositeExtract
// TODO: OpCompositeInsert