spirv-fuzz: Fix facts arising from CompositeConstruct (#4034)

Fixes #4023.
This commit is contained in:
Alastair Donaldson 2020-11-25 12:03:05 +00:00 committed by GitHub
parent 5ffa320fee
commit b0e22d28f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 4 deletions

View File

@ -283,15 +283,25 @@ void TransformationCompositeConstruct::AddDataSynonymFacts(
ir_context->get_type_mgr()->GetType(message_.composite_type_id());
uint32_t index = 0;
for (auto component : message_.component()) {
auto component_type = ir_context->get_type_mgr()->GetType(
ir_context->get_def_use_mgr()->GetDef(component)->type_id());
// Whether the component is a vector being packed into a vector determines
// how we should keep track of the indices associated with components.
const bool packing_vector_into_vector =
composite_type->AsVector() && component_type->AsVector();
if (!fuzzerutil::CanMakeSynonymOf(
ir_context, *transformation_context,
ir_context->get_def_use_mgr()->GetDef(component))) {
index++;
// We can't make a synonym of this component, so we skip on to the next
// component. In the case where we're packing a vector into a vector we
// have to skip as many components of the resulting vectors as there are
// elements of the component vector.
index += packing_vector_into_vector
? component_type->AsVector()->element_count()
: 1;
continue;
}
auto component_type = ir_context->get_type_mgr()->GetType(
ir_context->get_def_use_mgr()->GetDef(component)->type_id());
if (composite_type->AsVector() && component_type->AsVector()) {
if (packing_vector_into_vector) {
// The case where the composite being constructed is a vector and the
// component provided for construction is also a vector is special. It
// requires adding a synonym fact relating each element of the sub-vector

View File

@ -1643,6 +1643,55 @@ TEST(TransformationCompositeConstructTest, OneIrrelevantComponent) {
MakeDataDescriptor(100, {2}), MakeDataDescriptor(10, {})));
}
TEST(TransformationCompositeConstructTest, IrrelevantVec2ThenFloat) {
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 = OpTypeFloat 32
%7 = OpTypeVector %6 2
%8 = OpTypeVector %6 3
%9 = OpConstant %6 0
%11 = OpConstant %6 1
%12 = OpConstant %6 2
%10 = OpConstantComposite %7 %11 %12
%4 = OpFunction %2 None %3
%5 = 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(10);
TransformationCompositeConstruct transformation(
8, {10, 9}, MakeInstructionDescriptor(5, SpvOpReturn, 0), 100);
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(100, {0}), MakeDataDescriptor(10, {0})));
ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(100, {1}), MakeDataDescriptor(10, {1})));
ASSERT_TRUE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(100, {2}), MakeDataDescriptor(9, {})));
ASSERT_FALSE(transformation_context.GetFactManager()->IsSynonymous(
MakeDataDescriptor(100, {1}), MakeDataDescriptor(9, {})));
}
} // namespace
} // namespace fuzz
} // namespace spvtools