mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 19:20:05 +00:00
Check that if A calls B, B is defined before A for WebGPU (#2169)
Fixes #2067
This commit is contained in:
parent
68d1dc66d2
commit
3e645b9d67
@ -279,7 +279,15 @@ spv_result_t ValidateBinaryUsingContextAndValidationState(
|
||||
<< "A FunctionCall must happen within a function body.";
|
||||
}
|
||||
|
||||
vstate->AddFunctionCallTarget(inst->GetOperandAs<uint32_t>(2));
|
||||
const auto called_id = inst->GetOperandAs<uint32_t>(2);
|
||||
if (spvIsWebGPUEnv(context.target_env) &&
|
||||
!vstate->IsFunctionCallDefined(called_id)) {
|
||||
return vstate->diag(SPV_ERROR_INVALID_LAYOUT, &instruction)
|
||||
<< "For WebGPU, functions need to be defined before being "
|
||||
"called.";
|
||||
}
|
||||
|
||||
vstate->AddFunctionCallTarget(called_id);
|
||||
}
|
||||
|
||||
if (vstate->in_function_body()) {
|
||||
|
@ -280,6 +280,9 @@ class ValidationState_t {
|
||||
return (function_call_targets_.find(id) != function_call_targets_.end());
|
||||
}
|
||||
|
||||
bool IsFunctionCallDefined(const uint32_t id) {
|
||||
return (id_to_function_.find(id) != id_to_function_.end());
|
||||
}
|
||||
/// Registers the capability and its dependent capabilities
|
||||
void RegisterCapability(SpvCapability cap);
|
||||
|
||||
|
@ -648,6 +648,57 @@ TEST_F(ValidateLayout, ModuleProcessedInvalidInBasicBlock) {
|
||||
HasSubstr("ModuleProcessed cannot appear in a function declaration"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateLayout, WebGPUCallerBeforeCalleeBad) {
|
||||
char str[] = R"(
|
||||
OpCapability Shader
|
||||
OpCapability VulkanMemoryModelKHR
|
||||
OpExtension "SPV_KHR_vulkan_memory_model"
|
||||
OpMemoryModel Logical VulkanKHR
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
%void = OpTypeVoid
|
||||
%voidfn = OpTypeFunction %void
|
||||
%main = OpFunction %void None %voidfn
|
||||
%1 = OpLabel
|
||||
%2 = OpFunctionCall %void %callee
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%callee = OpFunction %void None %voidfn
|
||||
%3 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(str, SPV_ENV_WEBGPU_0);
|
||||
ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_WEBGPU_0));
|
||||
EXPECT_THAT(getDiagnosticString(),
|
||||
HasSubstr("For WebGPU, functions need to be defined before being "
|
||||
"called.\n %5 = OpFunctionCall %void %6\n"));
|
||||
}
|
||||
|
||||
TEST_F(ValidateLayout, WebGPUCalleeBeforeCallerGood) {
|
||||
char str[] = R"(
|
||||
OpCapability Shader
|
||||
OpCapability VulkanMemoryModelKHR
|
||||
OpExtension "SPV_KHR_vulkan_memory_model"
|
||||
OpMemoryModel Logical VulkanKHR
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
%void = OpTypeVoid
|
||||
%voidfn = OpTypeFunction %void
|
||||
%callee = OpFunction %void None %voidfn
|
||||
%3 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%main = OpFunction %void None %voidfn
|
||||
%1 = OpLabel
|
||||
%2 = OpFunctionCall %void %callee
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
CompileSuccessfully(str, SPV_ENV_WEBGPU_0);
|
||||
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
|
||||
}
|
||||
|
||||
// TODO(umar): Test optional instructions
|
||||
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user