spirv-fuzz: Handle image storage class in donation (#3290)

Demotes the image storage class to Private during donation.  Also
fixes an issue where instructions that depended on non-donated global
values would not be handled properly.
This commit is contained in:
Alastair Donaldson 2020-04-14 20:21:33 +01:00 committed by GitHub
parent f82d47003e
commit 2f180468a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 4 deletions

View File

@ -124,6 +124,7 @@ SpvStorageClass FuzzerPassDonateModules::AdaptStorageClass(
case SpvStorageClassUniform:
case SpvStorageClassUniformConstant:
case SpvStorageClassPushConstant:
case SpvStorageClassImage:
// We change these to Private
return SpvStorageClassPrivate;
default:
@ -721,11 +722,12 @@ bool FuzzerPassDonateModules::CanDonateInstruction(
// We do not have a mapped result id for this id operand. That either
// means that it is a forward reference (which is OK), that we skipped
// the instruction that generated it (which is not OK), or that it is
// the id of a function that we did not donate (which is not OK). We
// check for the latter two cases.
// the id of a function or global value that we did not donate (which
// is not OK). We check for the latter two cases.
if (skipped_instructions.count(*in_id) ||
donor_ir_context->get_def_use_mgr()->GetDef(*in_id)->opcode() ==
SpvOpFunction) {
// A function or global value does not have an associated basic
// block.
!donor_ir_context->get_instr_block(*in_id)) {
result = false;
return false;
}

View File

@ -1058,6 +1058,85 @@ TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageFunctionParameter) {
ASSERT_TRUE(IsValid(env, recipient_context.get()));
}
TEST(FuzzerPassDonateModulesTest, DonateShaderWithImageStorageClass) {
std::string recipient_shader = R"(
OpCapability Shader
OpCapability ImageQuery
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 320
OpSourceExtension "GL_EXT_samplerless_texture_functions"
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%4 = OpFunction %2 None %3
%5 = OpLabel
OpReturn
OpFunctionEnd
)";
std::string donor_shader = R"(
OpCapability Shader
OpCapability SampledBuffer
OpCapability ImageBuffer
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "MainPSPacked"
OpExecutionMode %2 OriginUpperLeft
OpDecorate %18 DescriptorSet 0
OpDecorate %18 Binding 128
%49 = OpTypeInt 32 0
%50 = OpTypeFloat 32
%58 = OpConstant %50 1
%66 = OpConstant %49 0
%87 = OpTypeVector %50 2
%88 = OpConstantComposite %87 %58 %58
%17 = OpTypeImage %49 2D 2 0 0 2 R32ui
%118 = OpTypePointer UniformConstant %17
%123 = OpTypeVector %49 2
%132 = OpTypeVoid
%133 = OpTypeFunction %132
%142 = OpTypePointer Image %49
%18 = OpVariable %118 UniformConstant
%2 = OpFunction %132 None %133
%153 = OpLabel
%495 = OpConvertFToU %123 %88
%501 = OpImageTexelPointer %142 %18 %495 %66
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto recipient_context =
BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, recipient_context.get()));
const auto donor_context =
BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
ASSERT_TRUE(IsValid(env, donor_context.get()));
FactManager fact_manager;
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(&fact_manager,
validator_options);
PseudoRandomGenerator prng(0);
FuzzerContext fuzzer_context(&prng, 100);
protobufs::TransformationSequence transformation_sequence;
FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
&transformation_context, &fuzzer_context,
&transformation_sequence, {});
fuzzer_pass.DonateSingleModule(donor_context.get(), true);
// We just check that the result is valid. Checking to what it should be
// exactly equal to would be very fragile.
ASSERT_TRUE(IsValid(env, recipient_context.get()));
}
TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArray) {
std::string recipient_shader = R"(
OpCapability Shader