Validate physical storage buffer restrictions (#2930)

* Physical storage buffer cannot be used with OpConstantNull,
OpPtrEqual, OpPtrNotEqual or OpPtrDiff
  * new tests
  * see also #2929
This commit is contained in:
alan-baker 2019-10-02 21:12:57 -04:00 committed by GitHub
parent 44b32176ee
commit 9d7428b052
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 122 additions and 3 deletions

View File

@ -304,7 +304,6 @@ bool IsTypeNullable(const std::vector<uint32_t>& instruction,
case SpvOpTypeBool:
case SpvOpTypeInt:
case SpvOpTypeFloat:
case SpvOpTypePointer:
case SpvOpTypeEvent:
case SpvOpTypeDeviceEvent:
case SpvOpTypeReserveId:
@ -325,6 +324,11 @@ bool IsTypeNullable(const std::vector<uint32_t>& instruction,
}
return true;
}
case SpvOpTypePointer:
if (instruction[2] == SpvStorageClassPhysicalStorageBuffer) {
return false;
}
return true;
default:
return false;
}

View File

@ -1590,8 +1590,8 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _,
<< "Operand type must be a pointer";
}
SpvStorageClass sc = op1_type->GetOperandAs<SpvStorageClass>(1u);
if (_.addressing_model() == SpvAddressingModelLogical) {
SpvStorageClass sc = op1_type->GetOperandAs<SpvStorageClass>(1u);
if (sc != SpvStorageClassWorkgroup && sc != SpvStorageClassStorageBuffer) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Invalid pointer storage class";
@ -1602,6 +1602,9 @@ spv_result_t ValidatePtrComparison(ValidationState_t& _,
<< "Workgroup storage class pointer requires VariablePointers "
"capability to be specified";
}
} else if (sc == SpvStorageClassPhysicalStorageBuffer) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Cannot use a pointer in the PhysicalStorageBuffer storage class";
}
return SPV_SUCCESS;

View File

@ -608,10 +608,12 @@ OpReturn
OpFunctionEnd
)";
// Issue #2929: cannot use OpConstantNull of a physical storage buffer
// pointer.
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndCheck<InstBuffAddrCheckPass>(
defs_before + func_before, defs_after + func_after + new_funcs, true,
true, 7u, 23u, 2u);
false, 7u, 23u, 2u);
}
} // namespace

View File

@ -458,6 +458,26 @@ OpMemoryModel Logical GLSL450
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
TEST_F(ValidateConstant, NullPhysicalStorageBuffer) {
std::string spirv = R"(
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
OpCapability Linkage
OpExtension "SPV_KHR_physical_storage_buffer"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpName %ptr "ptr"
%int = OpTypeInt 32 0
%ptr = OpTypePointer PhysicalStorageBuffer %int
%null = OpConstantNull %ptr
)";
CompileSuccessfully(spirv);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("OpConstantNull Result Type <id> '1[%ptr]' cannot have "
"a null value"));
}
} // namespace
} // namespace val
} // namespace spvtools

View File

@ -4386,6 +4386,96 @@ OpFunctionEnd
"typed as OpTypeStruct, or an array of this type"));
}
TEST_F(ValidateMemory, PhysicalStorageBufferPtrEqual) {
const std::string spirv = R"(
OpCapability Shader
OpCapability Int64
OpCapability PhysicalStorageBufferAddresses
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%bool = OpTypeBool
%long = OpTypeInt 64 0
%long_0 = OpConstant %long 0
%ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%conv = OpConvertUToPtr %ptr_pssbo_long %long_0
%eq = OpPtrEqual %bool %conv %conv
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Cannot use a pointer in the PhysicalStorageBuffer storage class"));
}
TEST_F(ValidateMemory, PhysicalStorageBufferPtrNotEqual) {
const std::string spirv = R"(
OpCapability Shader
OpCapability Int64
OpCapability PhysicalStorageBufferAddresses
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%bool = OpTypeBool
%long = OpTypeInt 64 0
%long_0 = OpConstant %long 0
%ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%conv = OpConvertUToPtr %ptr_pssbo_long %long_0
%neq = OpPtrNotEqual %bool %conv %conv
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Cannot use a pointer in the PhysicalStorageBuffer storage class"));
}
TEST_F(ValidateMemory, PhysicalStorageBufferPtrDiff) {
const std::string spirv = R"(
OpCapability Shader
OpCapability Int64
OpCapability PhysicalStorageBufferAddresses
OpCapability VariablePointers
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
%void = OpTypeVoid
%long = OpTypeInt 64 0
%long_0 = OpConstant %long 0
%ptr_pssbo_long = OpTypePointer PhysicalStorageBuffer %long
%void_fn = OpTypeFunction %void
%main = OpFunction %void None %void_fn
%entry = OpLabel
%conv = OpConvertUToPtr %ptr_pssbo_long %long_0
%diff = OpPtrDiff %long %conv %conv
OpReturn
OpFunctionEnd
)";
CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_5);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Cannot use a pointer in the PhysicalStorageBuffer storage class"));
}
} // namespace
} // namespace val
} // namespace spvtools