mirror of
https://gitee.com/openharmony/third_party_spirv-tools
synced 2024-11-23 23:39:40 +00:00
spirv-fuzz: Don't flatten conditional if condition is irrelevant (#3944)
Fixes #3942.
This commit is contained in:
parent
a3d5378df6
commit
a8d7062fe5
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user