Allow forward pointer to be used in types generally (#4044)

Fixes #4042

* Allow types to have forward declarations as long as that declaration
  is an OpTypeForwardPointer
This commit is contained in:
alan-baker 2020-12-08 08:46:47 -05:00 коммит произвёл GitHub
Родитель bda102d7a7
Коммит 862d44a86e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 42 добавлений и 3 удалений

Просмотреть файл

@ -24,6 +24,7 @@
#include "DebugInfo.h"
#include "OpenCLDebugInfo100.h"
#include "source/macro.h"
#include "source/opcode.h"
#include "source/spirv_constant.h"
#include "source/spirv_target_env.h"
@ -491,6 +492,11 @@ bool spvIsInIdType(spv_operand_type_t type) {
std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
SpvOp opcode) {
std::function<bool(unsigned index)> out;
if (spvOpcodeGeneratesType(opcode)) {
// All types can use forward pointers.
out = [](unsigned) { return true; };
return out;
}
switch (opcode) {
case SpvOpExecutionMode:
case SpvOpExecutionModeId:
@ -503,7 +509,6 @@ std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
case SpvOpDecorateId:
case SpvOpDecorateStringGOOGLE:
case SpvOpMemberDecorateStringGOOGLE:
case SpvOpTypeStruct:
case SpvOpBranch:
case SpvOpLoopMerge:
out = [](unsigned) { return true; };

Просмотреть файл

@ -201,7 +201,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
ret = SPV_SUCCESS;
}
} else if (can_have_forward_declared_ids(i)) {
if (inst->opcode() == SpvOpTypeStruct &&
if (spvOpcodeGeneratesType(inst->opcode()) &&
!_.IsForwardPointer(operand_word)) {
ret = _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Operand " << _.getIdName(operand_word)

Просмотреть файл

@ -497,7 +497,7 @@ TEST_F(ValidateData, ids_should_be_validated_before_data) {
CompileSuccessfully(str.c_str());
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("ID 3[%3] has not been defined"));
HasSubstr("Operand 3[%3] requires a previous definition"));
}
TEST_F(ValidateData, matrix_bad_column_type) {
@ -944,6 +944,40 @@ TEST_F(ValidateData, webgpu_RTA_not_at_end_of_struct) {
"OpTypeStruct %_runtimearr_uint %uint\n"));
}
TEST_F(ValidateData, TypeForwardReference) {
std::string test = R"(
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
OpCapability Linkage
OpMemoryModel Logical GLSL450
OpTypeForwardPointer %1 PhysicalStorageBuffer
%2 = OpTypeStruct
%3 = OpTypeRuntimeArray %1
%1 = OpTypePointer PhysicalStorageBuffer %2
)";
CompileSuccessfully(test, SPV_ENV_UNIVERSAL_1_5);
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
}
TEST_F(ValidateData, TypeForwardReferenceMustBeForwardPointer) {
std::string test = R"(
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
OpCapability Linkage
OpMemoryModel Logical GLSL450
%1 = OpTypeStruct
%2 = OpTypeRuntimeArray %3
%3 = OpTypePointer PhysicalStorageBuffer %1
)";
CompileSuccessfully(test, SPV_ENV_UNIVERSAL_1_5);
ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Operand 3[%_ptr_PhysicalStorageBuffer__struct_1] "
"requires a previous definition"));
}
} // namespace
} // namespace val
} // namespace spvtools