[spirv-reader] Test nested if, switch

Bug: tint:3
Change-Id: I7b84523b765bd51ea7a65dc2de396a14b80fcc62
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20044
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/reader/spirv/function_cfg_test.cc b/src/reader/spirv/function_cfg_test.cc
index 42c2f01..255947a 100644
--- a/src/reader/spirv/function_cfg_test.cc
+++ b/src/reader/spirv/function_cfg_test.cc
@@ -448,6 +448,196 @@
       << assembly;
 }
 
+TEST_F(SpvParserTest,
+       ComputeBlockOrder_Nest_If_In_If) {
+  auto assembly = CommonTypes() + R"(
+     %100 = OpFunction %void None %voidfn
+
+     %10 = OpLabel
+     OpSelectionMerge %99 None
+     OpBranchConditional %cond %20 %50
+
+     %99 = OpLabel
+     OpReturn
+
+     %20 = OpLabel
+     OpSelectionMerge %49 None
+     OpBranchConditional %cond %30 %40
+
+     %49 = OpLabel
+     OpBranch %99
+
+     %30 = OpLabel
+     OpBranch %49
+
+     %40 = OpLabel
+     OpBranch %49
+
+     %50 = OpLabel
+     OpSelectionMerge %79 None
+     OpBranchConditional %cond %60 %70
+
+     %79 = OpLabel
+     OpBranch %99
+
+     %60 = OpLabel
+     OpBranch %79
+
+     %70 = OpLabel
+     OpBranch %79
+
+     OpFunctionEnd
+  )";
+  auto* p = parser(test::Assemble(assembly));
+  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
+  FunctionEmitter fe(p, *spirv_function(100));
+  fe.ComputeBlockOrderAndPositions();
+
+  EXPECT_THAT(fe.rspo(), ElementsAre(10, 20, 30, 40, 49, 50, 60, 70, 79, 99))
+      << assembly;
+}
+
+TEST_F(SpvParserTest,
+       ComputeBlockOrder_Nest_If_In_SwitchCase) {
+  auto assembly = CommonTypes() + R"(
+     %100 = OpFunction %void None %voidfn
+
+     %10 = OpLabel
+     OpSelectionMerge %99 None
+     OpSwitch %selector %50 20 %20 50 %50
+
+     %99 = OpLabel
+     OpReturn
+
+     %20 = OpLabel
+     OpSelectionMerge %49 None
+     OpBranchConditional %cond %30 %40
+
+     %49 = OpLabel
+     OpBranch %99
+
+     %30 = OpLabel
+     OpBranch %49
+
+     %40 = OpLabel
+     OpBranch %49
+
+     %50 = OpLabel
+     OpSelectionMerge %79 None
+     OpBranchConditional %cond %60 %70
+
+     %79 = OpLabel
+     OpBranch %99
+
+     %60 = OpLabel
+     OpBranch %79
+
+     %70 = OpLabel
+     OpBranch %79
+
+     OpFunctionEnd
+  )";
+  auto* p = parser(test::Assemble(assembly));
+  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
+  FunctionEmitter fe(p, *spirv_function(100));
+  fe.ComputeBlockOrderAndPositions();
+
+  EXPECT_THAT(fe.rspo(), ElementsAre(10, 20, 30, 40, 49, 50, 60, 70, 79, 99))
+      << assembly;
+}
+
+TEST_F(SpvParserTest,
+       ComputeBlockOrder_Nest_IfFallthrough_In_SwitchCase) {
+  auto assembly = CommonTypes() + R"(
+     %100 = OpFunction %void None %voidfn
+
+     %10 = OpLabel
+     OpSelectionMerge %99 None
+     OpSwitch %selector %50 20 %20 50 %50
+
+     %99 = OpLabel
+     OpReturn
+
+     %20 = OpLabel
+     OpSelectionMerge %49 None
+     OpBranchConditional %cond %30 %40
+
+     %49 = OpLabel
+     OpBranchConditional %cond %99 %50 ; fallthrough
+
+     %30 = OpLabel
+     OpBranch %49
+
+     %40 = OpLabel
+     OpBranch %49
+
+     %50 = OpLabel
+     OpSelectionMerge %79 None
+     OpBranchConditional %cond %60 %70
+
+     %79 = OpLabel
+     OpBranch %99
+
+     %60 = OpLabel
+     OpBranch %79
+
+     %70 = OpLabel
+     OpBranch %79
+
+     OpFunctionEnd
+  )";
+  auto* p = parser(test::Assemble(assembly));
+  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
+  FunctionEmitter fe(p, *spirv_function(100));
+  fe.ComputeBlockOrderAndPositions();
+
+  EXPECT_THAT(fe.rspo(), ElementsAre(10, 20, 30, 40, 49, 50, 60, 70, 79, 99))
+      << assembly;
+}
+
+TEST_F(SpvParserTest,
+       ComputeBlockOrder_Nest_IfBreak_In_SwitchCase) {
+  auto assembly = CommonTypes() + R"(
+     %100 = OpFunction %void None %voidfn
+
+     %10 = OpLabel
+     OpSelectionMerge %99 None
+     OpSwitch %selector %50 20 %20 50 %50
+
+     %99 = OpLabel
+     OpReturn
+
+     %20 = OpLabel
+     OpSelectionMerge %49 None
+     OpBranchConditional %cond %99 %40 ; break-if
+
+     %49 = OpLabel
+     OpBranch %99
+
+     %40 = OpLabel
+     OpBranch %49
+
+     %50 = OpLabel
+     OpSelectionMerge %79 None
+     OpBranchConditional %cond %60 %99 ; break-unless
+
+     %79 = OpLabel
+     OpBranch %99
+
+     %60 = OpLabel
+     OpBranch %79
+
+     OpFunctionEnd
+  )";
+  auto* p = parser(test::Assemble(assembly));
+  ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions()) << p->error();
+  FunctionEmitter fe(p, *spirv_function(100));
+  fe.ComputeBlockOrderAndPositions();
+
+  EXPECT_THAT(fe.rspo(), ElementsAre(10, 20, 40, 49, 50, 60, 79, 99))
+      << assembly;
+}
+
 // TODO(dneto): test nesting
 // TODO(dneto): test loops