spirv-fuzz: Add illustrative tests for new issues (#4347)

Adds (currently disabled) tests related to #4345 and #4346.
This commit is contained in:
Alastair Donaldson 2021-06-24 17:24:46 +01:00 committed by GitHub
parent 3a02d11268
commit 8cc8b6562b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1796,6 +1796,241 @@ TEST(TransformationReplaceIdWithSynonymTest, IncompatibleTypes) {
.IsApplicable(context.get(), transformation_context));
}
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/4346): This test
// should be updated to cover more atomic operations, and once the issue is
// fixed the test should be enabled.
TEST(TransformationReplaceIdWithSynonymTest,
DISABLED_AtomicScopeAndMemorySemanticsMustBeConstant) {
// The following SPIR-V came from this GLSL, edited to add some synonyms:
//
// #version 320 es
//
// #extension GL_KHR_memory_scope_semantics : enable
//
// layout(set = 0, binding = 0) buffer Buf {
// int x;
// };
//
// void main() {
// int tmp = atomicLoad(x,
// gl_ScopeWorkgroup,
// gl_StorageSemanticsBuffer,
// gl_SemanticsRelaxed);
// }
const std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 320
OpSourceExtension "GL_KHR_memory_scope_semantics"
OpMemberDecorate %9 0 Offset 0
OpDecorate %9 Block
OpDecorate %11 DescriptorSet 0
OpDecorate %11 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%7 = OpTypePointer Function %6
%9 = OpTypeStruct %6
%10 = OpTypePointer StorageBuffer %9
%11 = OpVariable %10 StorageBuffer
%12 = OpConstant %6 0
%13 = OpTypePointer StorageBuffer %6
%15 = OpConstant %6 2
%16 = OpConstant %6 64
%17 = OpTypeInt 32 0
%18 = OpConstant %17 1
%19 = OpConstant %17 0
%20 = OpConstant %17 64
%4 = OpFunction %2 None %3
%5 = OpLabel
%8 = OpVariable %7 Function
%100 = OpCopyObject %6 %15 ; A non-constant version of %15
%101 = OpCopyObject %17 %20 ; A non-constant version of %20
%14 = OpAccessChain %13 %11 %12
%21 = OpAtomicLoad %6 %14 %15 %20
OpStore %8 %21
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
spvtools::ValidatorOptions validator_options;
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
// Tell the fact manager that %100 and %15 are synonymous
transformation_context.GetFactManager()->AddFactDataSynonym(
MakeDataDescriptor(100, {}), MakeDataDescriptor(15, {}));
// Tell the fact manager that %101 and %20 are synonymous
transformation_context.GetFactManager()->AddFactDataSynonym(
MakeDataDescriptor(101, {}), MakeDataDescriptor(20, {}));
const auto& scope_operand = MakeIdUseDescriptorFromUse(
context.get(), context->get_def_use_mgr()->GetDef(21), 1);
ASSERT_FALSE(TransformationReplaceIdWithSynonym(scope_operand, 100)
.IsApplicable(context.get(), transformation_context));
const auto& semantics_operand = MakeIdUseDescriptorFromUse(
context.get(), context->get_def_use_mgr()->GetDef(21), 2);
ASSERT_FALSE(TransformationReplaceIdWithSynonym(semantics_operand, 101)
.IsApplicable(context.get(), transformation_context));
}
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/4345): Improve this
// test so that it covers more atomic operations, and enable the test once the
// issue is fixed.
TEST(TransformationReplaceIdWithSynonymTest,
DISABLED_SignOfAtomicScopeAndMemorySemanticsDoesNotMatter) {
// TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/4345): both the
// GLSL comment and the corresponding SPIR-V should be updated to cover a
// larger number of atomic operations.
// The following SPIR-V came from this GLSL, edited to add some synonyms:
//
// #version 320 es
//
// #extension GL_KHR_memory_scope_semantics : enable
//
// layout(set = 0, binding = 0) buffer Buf {
// int x;
// };
//
// void main() {
// int tmp = atomicLoad(x,
// gl_ScopeWorkgroup,
// gl_StorageSemanticsBuffer,
// gl_SemanticsRelaxed);
// }
const std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 320
OpSourceExtension "GL_KHR_memory_scope_semantics"
OpMemberDecorate %9 0 Offset 0
OpDecorate %9 Block
OpDecorate %11 DescriptorSet 0
OpDecorate %11 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%7 = OpTypePointer Function %6
%9 = OpTypeStruct %6
%10 = OpTypePointer StorageBuffer %9
%11 = OpVariable %10 StorageBuffer
%12 = OpConstant %6 0
%13 = OpTypePointer StorageBuffer %6
%15 = OpConstant %6 2
%16 = OpConstant %6 64
%17 = OpTypeInt 32 0
%100 = OpConstant %17 2 ; The same as %15, but with unsigned int type
%18 = OpConstant %17 1
%19 = OpConstant %17 0
%20 = OpConstant %17 64
%101 = OpConstant %6 64 ; The same as %20, but with signed int type
%4 = OpFunction %2 None %3
%5 = OpLabel
%8 = OpVariable %7 Function
%14 = OpAccessChain %13 %11 %12
%21 = OpAtomicLoad %6 %14 %15 %20
OpStore %8 %21
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
spvtools::ValidatorOptions validator_options;
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
kConsoleMessageConsumer));
TransformationContext transformation_context(
MakeUnique<FactManager>(context.get()), validator_options);
// Tell the fact manager that %100 and %15 are synonymous
transformation_context.GetFactManager()->AddFactDataSynonym(
MakeDataDescriptor(100, {}), MakeDataDescriptor(15, {}));
// Tell the fact manager that %101 and %20 are synonymous
transformation_context.GetFactManager()->AddFactDataSynonym(
MakeDataDescriptor(101, {}), MakeDataDescriptor(20, {}));
{
const auto& scope_operand = MakeIdUseDescriptorFromUse(
context.get(), context->get_def_use_mgr()->GetDef(21), 1);
TransformationReplaceIdWithSynonym replace_scope(scope_operand, 100);
ASSERT_TRUE(
replace_scope.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(replace_scope, context.get(),
&transformation_context);
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
context.get(), validator_options, kConsoleMessageConsumer));
}
{
const auto& semantics_operand = MakeIdUseDescriptorFromUse(
context.get(), context->get_def_use_mgr()->GetDef(21), 2);
TransformationReplaceIdWithSynonym replace_semantics(semantics_operand,
101);
ASSERT_TRUE(
replace_semantics.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(replace_semantics, context.get(),
&transformation_context);
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
context.get(), validator_options, kConsoleMessageConsumer));
}
const std::string after_transformation = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %4 "main"
OpExecutionMode %4 LocalSize 1 1 1
OpSource ESSL 320
OpSourceExtension "GL_KHR_memory_scope_semantics"
OpMemberDecorate %9 0 Offset 0
OpDecorate %9 Block
OpDecorate %11 DescriptorSet 0
OpDecorate %11 Binding 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%7 = OpTypePointer Function %6
%9 = OpTypeStruct %6
%10 = OpTypePointer StorageBuffer %9
%11 = OpVariable %10 StorageBuffer
%12 = OpConstant %6 0
%13 = OpTypePointer StorageBuffer %6
%15 = OpConstant %6 2
%16 = OpConstant %6 64
%17 = OpTypeInt 32 0
%100 = OpConstant %17 2
%18 = OpConstant %17 1
%19 = OpConstant %17 0
%20 = OpConstant %17 64
%101 = OpConstant %6 64
%4 = OpFunction %2 None %3
%5 = OpLabel
%8 = OpVariable %7 Function
%14 = OpAccessChain %13 %11 %12
%21 = OpAtomicLoad %6 %14 %100 %101
OpStore %8 %21
OpReturn
OpFunctionEnd
)";
ASSERT_TRUE(IsEqual(env, after_transformation, context.get()));
}
} // namespace
} // namespace fuzz
} // namespace spvtools