spirv-fuzz: Do not outline regions that end with a loop header (#3312)
The outliner would outline regions ending with a loop header, making
the block containing the call to the outlined function serve as the
loop header. This, however, is incorrect in general, since the whole
outlined function -- rather than just the exit block for the region --
would end up getting called every time the loop would iterate.
This change restricts the outliner so that the last block in a region
cannot be a loop header.
diff --git a/source/fuzz/transformation_outline_function.cpp b/source/fuzz/transformation_outline_function.cpp
index d84545a..05fd923 100644
--- a/source/fuzz/transformation_outline_function.cpp
+++ b/source/fuzz/transformation_outline_function.cpp
@@ -200,21 +200,13 @@
// It is OK (and typically expected) for the exit block of the region to
// have successors outside the region.
//
- // It is also OK for the exit block to head a structured control flow
- // construct - the block containing the call to the outlined function will
- // end up heading this construct if outlining takes place. However, we
- // must ensure that if the exit block heads a loop, the continue target
- // for this loop is outside the region.
- if (auto loop_merge = block.GetLoopMergeInst()) {
- // The exit block heads a loop
- auto continue_target =
- ir_context->cfg()->block(loop_merge->GetSingleWordOperand(1));
- if (region_set.count(continue_target)) {
- // The continue target for the loop is in the region.
- return false;
- }
+ // It is also OK for the exit block to head a selection construct: the
+ // block containing the call to the outlined function will end up heading
+ // this construct if outlining takes place. However, it is not OK for
+ // the exit block to head a loop construct.
+ if (block.GetLoopMergeInst()) {
+ return false;
}
-
continue;
}
diff --git a/test/fuzz/transformation_outline_function_test.cpp b/test/fuzz/transformation_outline_function_test.cpp
index 01bba31..ed4fd15 100644
--- a/test/fuzz/transformation_outline_function_test.cpp
+++ b/test/fuzz/transformation_outline_function_test.cpp
@@ -2519,10 +2519,9 @@
transformation.IsApplicable(context.get(), transformation_context));
}
-TEST(TransformationOutlineFunctionTest,
- ExitBlockHeadsLoopButContinueConstructIsInRegion) {
+TEST(TransformationOutlineFunctionTest, ExitBlockHeadsLoop) {
// This checks that it is not possible outline a region that ends in a loop
- // head if the continue target for the loop is inside the region.
+ // head.
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"