From cd1d3b6e0c7d6f3c69dd549abbcdeb9089bafeb9 Mon Sep 17 00:00:00 2001 From: Alastair Donaldson Date: Mon, 19 Oct 2020 17:32:56 +0100 Subject: [PATCH] spirv-fuzz: Handle dead blocks in TransformationEquationInstruction (#3933) Fixes #3926. --- .../transformation_equation_instruction.cpp | 13 +++-- ...ansformation_equation_instruction_test.cpp | 57 +++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/source/fuzz/transformation_equation_instruction.cpp b/source/fuzz/transformation_equation_instruction.cpp index 173b0d420..32e835185 100644 --- a/source/fuzz/transformation_equation_instruction.cpp +++ b/source/fuzz/transformation_equation_instruction.cpp @@ -50,8 +50,8 @@ bool TransformationEquationInstruction::IsApplicable( if (!insert_before) { return false; } - // The input ids must all exist, not be OpUndef, and be available before this - // instruction. + // The input ids must all exist, not be OpUndef, not be irrelevant, and be + // available before this instruction. for (auto id : message_.in_operand_id()) { auto inst = ir_context->get_def_use_mgr()->GetDef(id); if (!inst) { @@ -92,8 +92,13 @@ void TransformationEquationInstruction::Apply( ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone); - transformation_context->GetFactManager()->AddFactIdEquation( - message_.fresh_id(), static_cast(message_.opcode()), rhs_id); + // Add an equation fact as long as the result id is not irrelevant (it could + // be if we are inserting into a dead block). + if (!transformation_context->GetFactManager()->IdIsIrrelevant( + message_.fresh_id())) { + transformation_context->GetFactManager()->AddFactIdEquation( + message_.fresh_id(), static_cast(message_.opcode()), rhs_id); + } } protobufs::Transformation TransformationEquationInstruction::ToMessage() const { diff --git a/test/fuzz/transformation_equation_instruction_test.cpp b/test/fuzz/transformation_equation_instruction_test.cpp index e937588cd..654fffcbb 100644 --- a/test/fuzz/transformation_equation_instruction_test.cpp +++ b/test/fuzz/transformation_equation_instruction_test.cpp @@ -1618,6 +1618,63 @@ TEST(TransformationEquationInstructionTest, HandlesIrrelevantIds) { transformation.IsApplicable(context.get(), transformation_context)); } +TEST(TransformationEquationInstructionTest, HandlesDeadBlock) { + std::string shader = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %12 "main" + OpExecutionMode %12 OriginUpperLeft + OpSource ESSL 310 + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeInt 32 1 + %30 = OpTypeVector %6 3 + %15 = OpConstant %6 24 + %16 = OpConstant %6 37 + %31 = OpConstantComposite %30 %15 %16 %15 + %33 = OpTypeBool + %32 = OpConstantTrue %33 + %12 = OpFunction %2 None %3 + %13 = OpLabel + OpSelectionMerge %40 None + OpBranchConditional %32 %40 %41 + %41 = OpLabel + OpBranch %40 + %40 = OpLabel + 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(context.get()), validator_options); + + transformation_context.GetFactManager()->AddFactBlockIsDead(41); + + TransformationEquationInstruction transformation1( + 14, SpvOpIAdd, {15, 16}, + MakeInstructionDescriptor(13, SpvOpSelectionMerge, 0)); + // No synonym is created since block is dead. + TransformationEquationInstruction transformation2( + 100, SpvOpISub, {14, 16}, MakeInstructionDescriptor(41, SpvOpBranch, 0)); + ASSERT_TRUE( + transformation1.IsApplicable(context.get(), transformation_context)); + ApplyAndCheckFreshIds(transformation1, context.get(), + &transformation_context); + ASSERT_TRUE( + transformation2.IsApplicable(context.get(), transformation_context)); + ApplyAndCheckFreshIds(transformation2, context.get(), + &transformation_context); + ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous( + MakeDataDescriptor(100, {}), MakeDataDescriptor(15, {}))); +} + } // namespace } // namespace fuzz } // namespace spvtools