aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralan-baker <alanbaker@google.com>2022-12-12 10:49:59 -0500
committerGitHub <noreply@github.com>2022-12-12 10:49:59 -0500
commit235182cfee2cf03a6f05f7c62b7927584b955850 (patch)
tree7dd132d4f3fabce2bf73653aa80b573203771c2e
parent9c6a925c87d4c6e203e440ecc8a57018e5bb8c4b (diff)
downloadspirv-tools-235182cfee2cf03a6f05f7c62b7927584b955850.tar.gz
Fix use of invalid analysis (#5013)
Fixes https://crbug.com/1395415 * Block merging needed to invalid structured cfg analysis
-rw-r--r--source/opt/block_merge_util.cpp5
-rw-r--r--test/opt/block_merge_test.cpp33
2 files changed, 38 insertions, 0 deletions
diff --git a/source/opt/block_merge_util.cpp b/source/opt/block_merge_util.cpp
index a893ab53..fe23e36f 100644
--- a/source/opt/block_merge_util.cpp
+++ b/source/opt/block_merge_util.cpp
@@ -171,6 +171,11 @@ void MergeWithSuccessor(IRContext* context, Function* func,
// sbi must follow bi in func's ordering.
assert(sbi != func->end());
+ if (sbi->tail()->opcode() == spv::Op::OpSwitch &&
+ sbi->MergeBlockIdIfAny() != 0) {
+ context->InvalidateAnalyses(IRContext::Analysis::kAnalysisStructuredCFG);
+ }
+
// Update the inst-to-block mapping for the instructions in sbi.
for (auto& inst : *sbi) {
context->set_instr_block(&inst, &*bi);
diff --git a/test/opt/block_merge_test.cpp b/test/opt/block_merge_test.cpp
index 6129bb27..57c5061f 100644
--- a/test/opt/block_merge_test.cpp
+++ b/test/opt/block_merge_test.cpp
@@ -1287,6 +1287,39 @@ OpFunctionEnd
EXPECT_EQ(opt::Pass::Status::SuccessWithoutChange, std::get<1>(result));
}
+TEST_F(BlockMergeTest, RebuildStructuredCFG) {
+ const std::string text = R"(
+; CHECK: = OpFunction
+; CHECK-NEXT: [[entry:%\w+]] = OpLabel
+; CHECK-NEXT: OpSelectionMerge [[merge:%\w+]] None
+; CHECK-NEXT: OpSwitch {{%\w+}} [[merge]] 0 [[other:%\w+]]
+; CHECK [[other]] = OpLabel
+; CHECK: OpBranch [[merge]]
+; CHECK [[merge]] = OpLabel
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_1 = OpConstant %int 1
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpBranch %switch
+%switch = OpLabel
+OpSelectionMerge %merge None
+OpSwitch %int_1 %merge 0 %other
+%other = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<BlockMergePass>(text, true);
+}
+
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// More complex control flow