spirv-fuzz: Enhancing permute function variables and its testing (#4295)

Fixes the way instruction swapping is implemented.

Fixes #4257.
Fixes #4259.
This commit is contained in:
Mostafa Ashraf 2021-05-26 01:41:31 +02:00 committed by GitHub
parent e2ac64bdf0
commit 00ce2bb474
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 6 deletions

View File

@ -31,10 +31,10 @@ FuzzerPassPermuteFunctionVariables::FuzzerPassPermuteFunctionVariables(
FuzzerContext* fuzzer_context,
protobufs::TransformationSequence* transformations)
: FuzzerPass(ir_context, transformation_context, fuzzer_context,
transformations) {} // Here we call parent constructor
transformations) {} // Here we call parent constructor.
void FuzzerPassPermuteFunctionVariables::Apply() {
// Permuting OpVariable instructions in each function
// Permuting OpVariable instructions in each function.
for (auto& function : *GetIRContext()->module()) {
if (!GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()->GetChanceOfPermutingFunctionVariables())) {
@ -49,7 +49,9 @@ void FuzzerPassPermuteFunctionVariables::Apply() {
variables.push_back(&instruction);
}
}
if (variables.size() <= 1) {
continue;
}
do {
uint32_t instruction_1_index = GetFuzzerContext()->RandomIndex(variables);
uint32_t instruction_2_index = GetFuzzerContext()->RandomIndex(variables);
@ -61,8 +63,9 @@ void FuzzerPassPermuteFunctionVariables::Apply() {
}
} while (GetFuzzerContext()->ChoosePercentage(
GetFuzzerContext()
->GetChanceOfSwappingAnotherPairOfFunctionVariables()));
GetFuzzerContext()
->GetChanceOfSwappingAnotherPairOfFunctionVariables()) &&
variables.size() > 2);
}
}

View File

@ -68,7 +68,13 @@ void TransformationSwapFunctionVariables::Apply(
auto instruction2 =
ir_context->get_def_use_mgr()->GetDef(message_.result_id2());
std::swap(*instruction1, *instruction2);
std::unique_ptr<opt::Instruction> temp_instruction =
MakeUnique<opt::Instruction>();
temp_instruction->InsertBefore(instruction1);
instruction1->InsertAfter(instruction2);
instruction2->InsertAfter(temp_instruction.get());
temp_instruction->RemoveFromList();
}
protobufs::Transformation TransformationSwapFunctionVariables::ToMessage()

View File

@ -175,6 +175,7 @@ TEST(TransformationSwapFunctionVariables, IsApplicable) {
const auto env = SPV_ENV_UNIVERSAL_1_5;
const auto consumer = nullptr;
// Get Unique pointer of IRContext.
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);
spvtools::ValidatorOptions validator_options;
@ -185,24 +186,40 @@ TEST(TransformationSwapFunctionVariables, IsApplicable) {
// Successful transformations
{
auto first_instruction = context->get_def_use_mgr()->GetDef(24);
auto second_instruction = context->get_def_use_mgr()->GetDef(28);
// Swap two OpVariable instructions in the same function.
TransformationSwapFunctionVariables transformation(24, 28);
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
context.get(), validator_options, kConsoleMessageConsumer));
ASSERT_EQ(first_instruction, context->get_def_use_mgr()->GetDef(24));
ASSERT_EQ(second_instruction, context->get_def_use_mgr()->GetDef(28));
}
{
auto first_instruction = context->get_def_use_mgr()->GetDef(38);
auto second_instruction = context->get_def_use_mgr()->GetDef(40);
// Swap two OpVariable instructions in the same function.
TransformationSwapFunctionVariables transformation(38, 40);
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(),
&transformation_context);
ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(
context.get(), validator_options, kConsoleMessageConsumer));
ASSERT_EQ(first_instruction, context->get_def_use_mgr()->GetDef(38));
ASSERT_EQ(second_instruction, context->get_def_use_mgr()->GetDef(40));
}
std::string after_transformation = R"(
OpCapability Shader