Fix use of invalid analysis (#5013)

Fixes https://crbug.com/1395415

* Block merging needed to invalid structured cfg analysis
diff --git a/source/opt/block_merge_util.cpp b/source/opt/block_merge_util.cpp
index a893ab5..fe23e36 100644
--- a/source/opt/block_merge_util.cpp
+++ b/source/opt/block_merge_util.cpp
@@ -171,6 +171,11 @@
   // 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 6129bb2..57c5061 100644
--- a/test/opt/block_merge_test.cpp
+++ b/test/opt/block_merge_test.cpp
@@ -1287,6 +1287,39 @@
   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