Skip to content

Commit

Permalink
spirv-fuzz: Support dead blocks in TransformationAddSynonym (#3832)
Browse files Browse the repository at this point in the history
Fixes #3830.
  • Loading branch information
Vasniktel authored Sep 24, 2020
1 parent 36185f8 commit 330c725
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 2 deletions.
6 changes: 6 additions & 0 deletions source/fuzz/fuzzer_pass_add_synonyms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ void FuzzerPassAddSynonyms::Apply() {
[this](opt::Function* function, opt::BasicBlock* block,
opt::BasicBlock::iterator inst_it,
const protobufs::InstructionDescriptor& instruction_descriptor) {
if (GetTransformationContext()->GetFactManager()->BlockIsDead(
block->id())) {
// Don't create synonyms in dead blocks.
return;
}

// Skip |inst_it| if we can't insert anything above it. OpIAdd is just
// a representative of some instruction that might be produced by the
// transformation.
Expand Down
6 changes: 6 additions & 0 deletions source/fuzz/fuzzer_pass_copy_objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ void FuzzerPassCopyObjects::Apply() {
"The opcode of the instruction we might insert before must be "
"the same as the opcode in the descriptor for the instruction");

if (GetTransformationContext()->GetFactManager()->BlockIsDead(
block->id())) {
// Don't create synonyms in dead blocks.
return;
}

// Check whether it is legitimate to insert a copy before this
// instruction.
if (!fuzzerutil::CanInsertOpcodeBeforeInstruction(SpvOpCopyObject,
Expand Down
11 changes: 11 additions & 0 deletions source/fuzz/transformation_add_synonym.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ bool TransformationAddSynonym::IsApplicable(
return false;
}

const auto* insert_before_inst_block =
ir_context->get_instr_block(insert_before_inst);
assert(insert_before_inst_block &&
"|insert_before_inst| must be in some block");

if (transformation_context.GetFactManager()->BlockIsDead(
insert_before_inst_block->id())) {
// We don't create synonyms in dead blocks.
return false;
}

// Check that we can insert |message._synonymous_instruction| before
// |message_.insert_before| instruction. We use OpIAdd to represent some
// instruction that can produce a synonym.
Expand Down
55 changes: 53 additions & 2 deletions test/fuzz/transformation_add_synonym_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@ TEST(TransformationAddSynonymTest, PropagateIrrelevantPointeeFact) {
transformation_context.GetFactManager()->PointeeValueIsIrrelevant(101));
}

TEST(TransformationAddSynonym, DoNotCopyOpSampledImage) {
TEST(TransformationAddSynonymTest, DoNotCopyOpSampledImage) {
// This checks that we do not try to copy the result id of an OpSampledImage
// instruction.
std::string shader = R"(
Expand Down Expand Up @@ -1392,7 +1392,7 @@ TEST(TransformationAddSynonym, DoNotCopyOpSampledImage) {
.IsApplicable(context.get(), transformation_context));
}

TEST(TransformationAddSynonym, DoNotCopyVoidRunctionResult) {
TEST(TransformationAddSynonymTest, DoNotCopyVoidRunctionResult) {
// This checks that we do not try to copy the result of a void function.
std::string shader = R"(
OpCapability Shader
Expand Down Expand Up @@ -1431,6 +1431,57 @@ TEST(TransformationAddSynonym, DoNotCopyVoidRunctionResult) {
.IsApplicable(context.get(), transformation_context));
}

TEST(TransformationAddSynonymTest, HandlesDeadBlocks) {
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 320
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeBool
%7 = OpConstantTrue %6
%11 = OpTypePointer Function %6
%4 = OpFunction %2 None %3
%5 = OpLabel
%12 = OpVariable %11 Function
OpSelectionMerge %10 None
OpBranchConditional %7 %8 %9
%8 = OpLabel
OpBranch %10
%9 = OpLabel
OpBranch %10
%10 = OpLabel
OpReturn
OpFunctionEnd
)";

const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption);

FactManager fact_manager(context.get());
spvtools::ValidatorOptions validator_options;
TransformationContext transformation_context(&fact_manager,
validator_options);

fact_manager.AddFactBlockIsDead(9);

auto insert_before = MakeInstructionDescriptor(9, SpvOpBranch, 0);

ASSERT_FALSE(TransformationAddSynonym(
7, protobufs::TransformationAddSynonym::COPY_OBJECT, 100,
insert_before)
.IsApplicable(context.get(), transformation_context));

ASSERT_FALSE(TransformationAddSynonym(
12, protobufs::TransformationAddSynonym::COPY_OBJECT, 100,
insert_before)
.IsApplicable(context.get(), transformation_context));
}

} // namespace
} // namespace fuzz
} // namespace spvtools

0 comments on commit 330c725

Please sign in to comment.