diff options
author | alan-baker <alanbaker@google.com> | 2022-12-12 10:49:59 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-12 10:49:59 -0500 |
commit | 235182cfee2cf03a6f05f7c62b7927584b955850 (patch) | |
tree | 7dd132d4f3fabce2bf73653aa80b573203771c2e | |
parent | 9c6a925c87d4c6e203e440ecc8a57018e5bb8c4b (diff) | |
download | spirv-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.cpp | 5 | ||||
-rw-r--r-- | test/opt/block_merge_test.cpp | 33 |
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 |