spirv-fuzz: Do not allow sampled image load when flattening conditionals (#3930)
Fixes #3928.
diff --git a/source/fuzz/transformation_flatten_conditional_branch.cpp b/source/fuzz/transformation_flatten_conditional_branch.cpp
index 7fc636a..86a0313 100644
--- a/source/fuzz/transformation_flatten_conditional_branch.cpp
+++ b/source/fuzz/transformation_flatten_conditional_branch.cpp
@@ -699,6 +699,15 @@
return false;
}
+ // We cannot handle a sampled image load, because we re-work loads using
+ // conditional branches and OpPhi instructions, and the result type of OpPhi
+ // cannot be OpTypeSampledImage.
+ if (instruction.opcode() == SpvOpLoad &&
+ ir_context->get_def_use_mgr()->GetDef(instruction.type_id())->opcode() ==
+ SpvOpTypeSampledImage) {
+ return false;
+ }
+
// We cannot handle instructions with an id which return a void type, if the
// result id is used in the module (e.g. a function call to a function that
// returns nothing).
diff --git a/test/fuzz/transformation_flatten_conditional_branch_test.cpp b/test/fuzz/transformation_flatten_conditional_branch_test.cpp
index fddfdaf..ba34933 100644
--- a/test/fuzz/transformation_flatten_conditional_branch_test.cpp
+++ b/test/fuzz/transformation_flatten_conditional_branch_test.cpp
@@ -1233,6 +1233,70 @@
kConsoleMessageConsumer));
}
+TEST(TransformationFlattenConditionalBranchTest, InapplicableSampledImageLoad) {
+ std::string shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %12 %96
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 320
+ OpDecorate %12 BuiltIn FragCoord
+ OpDecorate %91 DescriptorSet 0
+ OpDecorate %91 Binding 0
+ OpDecorate %96 Location 0
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+ %7 = OpTypeVector %6 2
+ %10 = OpTypeVector %6 4
+ %11 = OpTypePointer Input %10
+ %12 = OpVariable %11 Input
+ %21 = OpConstant %6 2
+ %24 = OpTypeInt 32 1
+ %33 = OpTypeBool
+ %35 = OpConstantTrue %33
+ %88 = OpTypeImage %6 2D 0 0 0 1 Unknown
+ %89 = OpTypeSampledImage %88
+ %90 = OpTypePointer UniformConstant %89
+ %91 = OpVariable %90 UniformConstant
+ %95 = OpTypePointer Output %10
+ %96 = OpVariable %95 Output
+ %200 = OpUndef %89
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+ OpBranch %28
+ %28 = OpLabel
+ OpSelectionMerge %38 None
+ OpBranchConditional %35 %32 %37
+ %32 = OpLabel
+ %40 = OpLoad %89 %91
+ OpBranch %38
+ %37 = OpLabel
+ OpBranch %38
+ %38 = 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);
+
+ ASSERT_FALSE(TransformationFlattenConditionalBranch(
+ 28, true,
+ {MakeSideEffectWrapperInfo(
+ MakeInstructionDescriptor(40, SpvOpLoad, 0), 100, 101,
+ 102, 103, 104, 200)})
+ .IsApplicable(context.get(), transformation_context));
+}
+
} // namespace
} // namespace fuzz
} // namespace spvtools