spirv-fuzz: Don't flatten conditional if condition is irrelevant (#3944)

Fixes #3942.
This commit is contained in:
Alastair Donaldson 2020-10-21 21:26:59 +01:00 committed by GitHub
parent a3d5378df6
commit a8d7062fe5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 2 deletions

View File

@ -47,10 +47,13 @@ void FuzzerPassFlattenConditionalBranches::Apply() {
continue;
}
// Only consider this block if it is the header of a conditional.
// Only consider this block if it is the header of a conditional, with a
// non-irrelevant condition.
if (block.GetMergeInst() &&
block.GetMergeInst()->opcode() == SpvOpSelectionMerge &&
block.terminator()->opcode() == SpvOpBranchConditional) {
block.terminator()->opcode() == SpvOpBranchConditional &&
!GetTransformationContext()->GetFactManager()->IdIsIrrelevant(
block.terminator()->GetSingleWordInOperand(0))) {
selection_headers.emplace_back(&block);
}
}

View File

@ -57,6 +57,15 @@ bool TransformationFlattenConditionalBranch::IsApplicable(
return false;
}
// The branch condition cannot be irrelevant: we will make reference to it
// multiple times and we need to be guaranteed that these references will
// yield the same result; if they are replaced by other ids that will not
// work.
if (transformation_context.GetFactManager()->IdIsIrrelevant(
header_block->terminator()->GetSingleWordInOperand(0))) {
return false;
}
std::set<uint32_t> used_fresh_ids;
// If ids have been provided to be used as vector guards for OpSelect

View File

@ -35,6 +35,8 @@ class TransformationFlattenConditionalBranch : public Transformation {
// - |message_.header_block_id| must be the label id of a reachable selection
// header, which ends with an OpBranchConditional instruction.
// - The condition of the OpBranchConditional instruction must not be an
// irrelevant id.
// - The header block and the merge block must describe a single-entry,
// single-exit region.
// - The region must not contain barrier or OpSampledImage instructions.

View File

@ -1846,6 +1846,47 @@ TEST(TransformationFlattenConditionalBranchTest, ApplicablePhiToSelectMatrix) {
ASSERT_TRUE(IsEqual(env, expected_shader, context.get()));
}
TEST(TransformationFlattenConditionalBranchTest,
InapplicableConditionIsIrrelevant) {
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
%10 = OpTypeInt 32 1
%4 = OpFunction %2 None %3
%5 = OpLabel
OpSelectionMerge %9 None
OpBranchConditional %7 %8 %9
%8 = OpLabel
OpBranch %9
%9 = 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<FactManager>(context.get()), validator_options);
transformation_context.GetFactManager()->AddFactIdIsIrrelevant(7);
// Inapplicable because the branch condition, %7, is irrelevant.
ASSERT_FALSE(TransformationFlattenConditionalBranch(5, true, 0, 0, 0, {})
.IsApplicable(context.get(), transformation_context));
}
} // namespace
} // namespace fuzz
} // namespace spvtools