tint/hlsl: fix RemoveContinueInSwitch transform to handle nested switch statements
Rework the transform so that it handles a continue within a switch
nested within switches within a loop. Also make the transform only
generate a single bool variable per loop, rather than per continue
statement.
Bug: tint:1080
Change-Id: I626cf4aa35e900ccc8ad08712ff1393c91587f10
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/151041
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ben Clayton <bclayton@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/test/tint/loops/continue_in_switch.wgsl.expected.dxc.hlsl b/test/tint/loops/continue_in_switch.wgsl.expected.dxc.hlsl
index ca926df..3ed9dc4 100644
--- a/test/tint/loops/continue_in_switch.wgsl.expected.dxc.hlsl
+++ b/test/tint/loops/continue_in_switch.wgsl.expected.dxc.hlsl
@@ -1,14 +1,12 @@
[numthreads(1, 1, 1)]
void f() {
+ bool tint_continue = false;
{
for(int i = 0; (i < 4); i = (i + 1)) {
- bool tint_continue = false;
+ tint_continue = false;
switch(i) {
case 0: {
- {
- tint_continue = true;
- break;
- }
+ tint_continue = true;
break;
}
default: {
diff --git a/test/tint/loops/continue_in_switch.wgsl.expected.fxc.hlsl b/test/tint/loops/continue_in_switch.wgsl.expected.fxc.hlsl
index ca926df..3ed9dc4 100644
--- a/test/tint/loops/continue_in_switch.wgsl.expected.fxc.hlsl
+++ b/test/tint/loops/continue_in_switch.wgsl.expected.fxc.hlsl
@@ -1,14 +1,12 @@
[numthreads(1, 1, 1)]
void f() {
+ bool tint_continue = false;
{
for(int i = 0; (i < 4); i = (i + 1)) {
- bool tint_continue = false;
+ tint_continue = false;
switch(i) {
case 0: {
- {
- tint_continue = true;
- break;
- }
+ tint_continue = true;
break;
}
default: {
diff --git a/test/tint/loops/multiple_continues.wgsl b/test/tint/loops/multiple_continues.wgsl
new file mode 100644
index 0000000..a57f773
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl
@@ -0,0 +1,18 @@
+@compute @workgroup_size(1)
+fn main() {
+ for (var i = 0; i < 2; i += 1) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ case 1: {
+ continue;
+ }
+ case 2: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.dxc.hlsl b/test/tint/loops/multiple_continues.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..21f9f90
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl.expected.dxc.hlsl
@@ -0,0 +1,30 @@
+[numthreads(1, 1, 1)]
+void main() {
+ bool tint_continue = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 1)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ case 1: {
+ tint_continue = true;
+ break;
+ }
+ case 2: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.fxc.hlsl b/test/tint/loops/multiple_continues.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..21f9f90
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl.expected.fxc.hlsl
@@ -0,0 +1,30 @@
+[numthreads(1, 1, 1)]
+void main() {
+ bool tint_continue = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 1)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ case 1: {
+ tint_continue = true;
+ break;
+ }
+ case 2: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.glsl b/test/tint/loops/multiple_continues.wgsl.expected.glsl
new file mode 100644
index 0000000..36c86d8
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl.expected.glsl
@@ -0,0 +1,31 @@
+#version 310 es
+
+void tint_symbol() {
+ {
+ for(int i = 0; (i < 2); i = (i + 1)) {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ case 1: {
+ continue;
+ break;
+ }
+ case 2: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.msl b/test/tint/loops/multiple_continues.wgsl.expected.msl
new file mode 100644
index 0000000..ed8fcc1
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl.expected.msl
@@ -0,0 +1,26 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ case 1: {
+ continue;
+ break;
+ }
+ case 2: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.spvasm b/test/tint/loops/multiple_continues.wgsl.expected.spvasm
new file mode 100644
index 0000000..4d6a668
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl.expected.spvasm
@@ -0,0 +1,57 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 29
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %i "i"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %i = OpVariable %_ptr_Function_int Function %6
+ OpStore %i %6
+ OpBranch %9
+ %9 = OpLabel
+ OpLoopMerge %10 %11 None
+ OpBranch %12
+ %12 = OpLabel
+ %14 = OpLoad %int %i
+ %16 = OpSLessThan %bool %14 %int_2
+ %13 = OpLogicalNot %bool %16
+ OpSelectionMerge %18 None
+ OpBranchConditional %13 %19 %18
+ %19 = OpLabel
+ OpBranch %10
+ %18 = OpLabel
+ %21 = OpLoad %int %i
+ OpSelectionMerge %20 None
+ OpSwitch %21 %22 0 %23 1 %24 2 %25
+ %23 = OpLabel
+ OpBranch %11
+ %24 = OpLabel
+ OpBranch %11
+ %25 = OpLabel
+ OpBranch %11
+ %22 = OpLabel
+ OpBranch %20
+ %20 = OpLabel
+ OpBranch %11
+ %11 = OpLabel
+ %26 = OpLoad %int %i
+ %28 = OpIAdd %int %26 %int_1
+ OpStore %i %28
+ OpBranch %9
+ %10 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.wgsl b/test/tint/loops/multiple_continues.wgsl.expected.wgsl
new file mode 100644
index 0000000..a80bcaf
--- /dev/null
+++ b/test/tint/loops/multiple_continues.wgsl.expected.wgsl
@@ -0,0 +1,18 @@
+@compute @workgroup_size(1)
+fn main() {
+ for(var i = 0; (i < 2); i += 1) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ case 1: {
+ continue;
+ }
+ case 2: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/multiple_switch.wgsl b/test/tint/loops/multiple_switch.wgsl
new file mode 100644
index 0000000..b3acc1f
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl
@@ -0,0 +1,21 @@
+@compute @workgroup_size(1)
+fn main() {
+ var i = 0;
+ for (var i = 0; i < 2; i += 1) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.dxc.hlsl b/test/tint/loops/multiple_switch.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..b61b6b5
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl.expected.dxc.hlsl
@@ -0,0 +1,35 @@
+[numthreads(1, 1, 1)]
+void main() {
+ int i = 0;
+ bool tint_continue = false;
+ {
+ for(int i_1 = 0; (i_1 < 2); i_1 = (i_1 + 1)) {
+ tint_continue = false;
+ switch(i_1) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ switch(i_1) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.fxc.hlsl b/test/tint/loops/multiple_switch.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..b61b6b5
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl.expected.fxc.hlsl
@@ -0,0 +1,35 @@
+[numthreads(1, 1, 1)]
+void main() {
+ int i = 0;
+ bool tint_continue = false;
+ {
+ for(int i_1 = 0; (i_1 < 2); i_1 = (i_1 + 1)) {
+ tint_continue = false;
+ switch(i_1) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ switch(i_1) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.glsl b/test/tint/loops/multiple_switch.wgsl.expected.glsl
new file mode 100644
index 0000000..290f1e3
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl.expected.glsl
@@ -0,0 +1,33 @@
+#version 310 es
+
+void tint_symbol() {
+ int i = 0;
+ {
+ for(int i_1 = 0; (i_1 < 2); i_1 = (i_1 + 1)) {
+ switch(i_1) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ switch(i_1) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.msl b/test/tint/loops/multiple_switch.wgsl.expected.msl
new file mode 100644
index 0000000..342db50
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl.expected.msl
@@ -0,0 +1,28 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ int i = 0;
+ for(int i_1 = 0; (i_1 < 2); i_1 = as_type<int>((as_type<uint>(i_1) + as_type<uint>(1)))) {
+ switch(i_1) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ switch(i_1) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.spvasm b/test/tint/loops/multiple_switch.wgsl.expected.spvasm
new file mode 100644
index 0000000..edf7850
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl.expected.spvasm
@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 32
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %i "i"
+ OpName %i_1 "i_1"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %i = OpVariable %_ptr_Function_int Function %6
+ %i_1 = OpVariable %_ptr_Function_int Function %6
+ OpStore %i %6
+ OpStore %i_1 %6
+ OpBranch %10
+ %10 = OpLabel
+ OpLoopMerge %11 %12 None
+ OpBranch %13
+ %13 = OpLabel
+ %15 = OpLoad %int %i_1
+ %17 = OpSLessThan %bool %15 %int_2
+ %14 = OpLogicalNot %bool %17
+ OpSelectionMerge %19 None
+ OpBranchConditional %14 %20 %19
+ %20 = OpLabel
+ OpBranch %11
+ %19 = OpLabel
+ %22 = OpLoad %int %i_1
+ OpSelectionMerge %21 None
+ OpSwitch %22 %23 0 %24
+ %24 = OpLabel
+ OpBranch %12
+ %23 = OpLabel
+ OpBranch %21
+ %21 = OpLabel
+ %26 = OpLoad %int %i_1
+ OpSelectionMerge %25 None
+ OpSwitch %26 %27 0 %28
+ %28 = OpLabel
+ OpBranch %12
+ %27 = OpLabel
+ OpBranch %25
+ %25 = OpLabel
+ OpBranch %12
+ %12 = OpLabel
+ %29 = OpLoad %int %i_1
+ %31 = OpIAdd %int %29 %int_1
+ OpStore %i_1 %31
+ OpBranch %10
+ %11 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.wgsl b/test/tint/loops/multiple_switch.wgsl.expected.wgsl
new file mode 100644
index 0000000..1ef17ce
--- /dev/null
+++ b/test/tint/loops/multiple_switch.wgsl.expected.wgsl
@@ -0,0 +1,20 @@
+@compute @workgroup_size(1)
+fn main() {
+ var i = 0;
+ for(var i = 0; (i < 2); i += 1) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl b/test/tint/loops/nested_loop_loop_switch.wgsl
new file mode 100644
index 0000000..f925971
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl
@@ -0,0 +1,14 @@
+@compute @workgroup_size(1)
+fn main() {
+ for (var i = 0; i < 2; i += 2) {
+ for (var j = 0; j < 2; j += 2) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.dxc.hlsl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..01759c8
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.dxc.hlsl
@@ -0,0 +1,26 @@
+[numthreads(1, 1, 1)]
+void main() {
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ bool tint_continue = false;
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.fxc.hlsl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..01759c8
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.fxc.hlsl
@@ -0,0 +1,26 @@
+[numthreads(1, 1, 1)]
+void main() {
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ bool tint_continue = false;
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.glsl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.glsl
new file mode 100644
index 0000000..a3ad0a3
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.glsl
@@ -0,0 +1,27 @@
+#version 310 es
+
+void tint_symbol() {
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl
new file mode 100644
index 0000000..a1f0843
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.msl
@@ -0,0 +1,20 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+ for(int j = 0; (j < 2); j = as_type<int>((as_type<uint>(j) + as_type<uint>(2)))) {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.spvasm b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.spvasm
new file mode 100644
index 0000000..16f154d
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.spvasm
@@ -0,0 +1,75 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 38
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %i "i"
+ OpName %j "j"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %i = OpVariable %_ptr_Function_int Function %6
+ %j = OpVariable %_ptr_Function_int Function %6
+ OpStore %i %6
+ OpBranch %9
+ %9 = OpLabel
+ OpLoopMerge %10 %11 None
+ OpBranch %12
+ %12 = OpLabel
+ %14 = OpLoad %int %i
+ %16 = OpSLessThan %bool %14 %int_2
+ %13 = OpLogicalNot %bool %16
+ OpSelectionMerge %18 None
+ OpBranchConditional %13 %19 %18
+ %19 = OpLabel
+ OpBranch %10
+ %18 = OpLabel
+ OpStore %j %6
+ OpBranch %21
+ %21 = OpLabel
+ OpLoopMerge %22 %23 None
+ OpBranch %24
+ %24 = OpLabel
+ %26 = OpLoad %int %j
+ %27 = OpSLessThan %bool %26 %int_2
+ %25 = OpLogicalNot %bool %27
+ OpSelectionMerge %28 None
+ OpBranchConditional %25 %29 %28
+ %29 = OpLabel
+ OpBranch %22
+ %28 = OpLabel
+ %31 = OpLoad %int %i
+ OpSelectionMerge %30 None
+ OpSwitch %31 %32 0 %33
+ %33 = OpLabel
+ OpBranch %23
+ %32 = OpLabel
+ OpBranch %30
+ %30 = OpLabel
+ OpBranch %23
+ %23 = OpLabel
+ %34 = OpLoad %int %j
+ %35 = OpIAdd %int %34 %int_2
+ OpStore %j %35
+ OpBranch %21
+ %22 = OpLabel
+ OpBranch %11
+ %11 = OpLabel
+ %36 = OpLoad %int %i
+ %37 = OpIAdd %int %36 %int_2
+ OpStore %i %37
+ OpBranch %9
+ %10 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.wgsl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.wgsl
new file mode 100644
index 0000000..8026320
--- /dev/null
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.wgsl
@@ -0,0 +1,14 @@
+@compute @workgroup_size(1)
+fn main() {
+ for(var i = 0; (i < 2); i += 2) {
+ for(var j = 0; (j < 2); j += 2) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl
new file mode 100644
index 0000000..020d6df
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl
@@ -0,0 +1,21 @@
+@compute @workgroup_size(1)
+fn main() {
+ for (var i = 0; i < 2; i += 2) {
+ switch(i) {
+ case 0: {
+ for (var j = 0; j < 2; j += 2) {
+ switch(j) {
+ case 0: {
+ continue; // j loop
+ }
+ default: {
+ }
+ }
+ }
+ continue; // i loop
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.dxc.hlsl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..305bfbd
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.dxc.hlsl
@@ -0,0 +1,40 @@
+[numthreads(1, 1, 1)]
+void main() {
+ bool tint_continue_1 = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ tint_continue_1 = false;
+ switch(i) {
+ case 0: {
+ bool tint_continue = false;
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ tint_continue = false;
+ switch(j) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ tint_continue_1 = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue_1) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.fxc.hlsl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..305bfbd
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.fxc.hlsl
@@ -0,0 +1,40 @@
+[numthreads(1, 1, 1)]
+void main() {
+ bool tint_continue_1 = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ tint_continue_1 = false;
+ switch(i) {
+ case 0: {
+ bool tint_continue = false;
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ tint_continue = false;
+ switch(j) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ tint_continue_1 = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue_1) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.glsl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.glsl
new file mode 100644
index 0000000..1e45661
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.glsl
@@ -0,0 +1,36 @@
+#version 310 es
+
+void tint_symbol() {
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ switch(i) {
+ case 0: {
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl
new file mode 100644
index 0000000..a5e768d
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.msl
@@ -0,0 +1,29 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+ switch(i) {
+ case 0: {
+ for(int j = 0; (j < 2); j = as_type<int>((as_type<uint>(j) + as_type<uint>(2)))) {
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.spvasm b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.spvasm
new file mode 100644
index 0000000..9509f0d
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.spvasm
@@ -0,0 +1,83 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 42
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %i "i"
+ OpName %j "j"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %i = OpVariable %_ptr_Function_int Function %6
+ %j = OpVariable %_ptr_Function_int Function %6
+ OpStore %i %6
+ OpBranch %9
+ %9 = OpLabel
+ OpLoopMerge %10 %11 None
+ OpBranch %12
+ %12 = OpLabel
+ %14 = OpLoad %int %i
+ %16 = OpSLessThan %bool %14 %int_2
+ %13 = OpLogicalNot %bool %16
+ OpSelectionMerge %18 None
+ OpBranchConditional %13 %19 %18
+ %19 = OpLabel
+ OpBranch %10
+ %18 = OpLabel
+ %21 = OpLoad %int %i
+ OpSelectionMerge %20 None
+ OpSwitch %21 %22 0 %23
+ %23 = OpLabel
+ OpStore %j %6
+ OpBranch %25
+ %25 = OpLabel
+ OpLoopMerge %26 %27 None
+ OpBranch %28
+ %28 = OpLabel
+ %30 = OpLoad %int %j
+ %31 = OpSLessThan %bool %30 %int_2
+ %29 = OpLogicalNot %bool %31
+ OpSelectionMerge %32 None
+ OpBranchConditional %29 %33 %32
+ %33 = OpLabel
+ OpBranch %26
+ %32 = OpLabel
+ %35 = OpLoad %int %j
+ OpSelectionMerge %34 None
+ OpSwitch %35 %36 0 %37
+ %37 = OpLabel
+ OpBranch %27
+ %36 = OpLabel
+ OpBranch %34
+ %34 = OpLabel
+ OpBranch %27
+ %27 = OpLabel
+ %38 = OpLoad %int %j
+ %39 = OpIAdd %int %38 %int_2
+ OpStore %j %39
+ OpBranch %25
+ %26 = OpLabel
+ OpBranch %11
+ %22 = OpLabel
+ OpBranch %20
+ %20 = OpLabel
+ OpBranch %11
+ %11 = OpLabel
+ %40 = OpLoad %int %i
+ %41 = OpIAdd %int %40 %int_2
+ OpStore %i %41
+ OpBranch %9
+ %10 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.wgsl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.wgsl
new file mode 100644
index 0000000..0398609
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.wgsl
@@ -0,0 +1,21 @@
+@compute @workgroup_size(1)
+fn main() {
+ for(var i = 0; (i < 2); i += 2) {
+ switch(i) {
+ case 0: {
+ for(var j = 0; (j < 2); j += 2) {
+ switch(j) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl
new file mode 100644
index 0000000..c152681
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl
@@ -0,0 +1,31 @@
+@compute @workgroup_size(1)
+fn main() {
+ var k = 0;
+ for (var i = 0; i < 2; i += 2) {
+ switch(i) {
+ case 0: {
+ for (var j = 0; j < 2; j += 2) {
+ switch(j) {
+ case 0: {
+ continue; // j loop
+ }
+ case 1: {
+ switch (k) {
+ case 0: {
+ continue; // j loop
+ }
+ default: {
+ }
+ }
+ }
+ default: {
+ }
+ }
+ }
+ continue; // i loop
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.dxc.hlsl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..7d646a9
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.dxc.hlsl
@@ -0,0 +1,56 @@
+[numthreads(1, 1, 1)]
+void main() {
+ int k = 0;
+ bool tint_continue_1 = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ tint_continue_1 = false;
+ switch(i) {
+ case 0: {
+ bool tint_continue = false;
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ tint_continue = false;
+ switch(j) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ case 1: {
+ switch(k) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ tint_continue_1 = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue_1) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.fxc.hlsl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..7d646a9
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.fxc.hlsl
@@ -0,0 +1,56 @@
+[numthreads(1, 1, 1)]
+void main() {
+ int k = 0;
+ bool tint_continue_1 = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ tint_continue_1 = false;
+ switch(i) {
+ case 0: {
+ bool tint_continue = false;
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ tint_continue = false;
+ switch(j) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ case 1: {
+ switch(k) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ tint_continue_1 = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue_1) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.glsl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.glsl
new file mode 100644
index 0000000..3c59535
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.glsl
@@ -0,0 +1,49 @@
+#version 310 es
+
+void tint_symbol() {
+ int k = 0;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ switch(i) {
+ case 0: {
+ {
+ for(int j = 0; (j < 2); j = (j + 2)) {
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ case 1: {
+ switch(k) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl
new file mode 100644
index 0000000..b3a1fd6
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.msl
@@ -0,0 +1,42 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ int k = 0;
+ for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+ switch(i) {
+ case 0: {
+ for(int j = 0; (j < 2); j = as_type<int>((as_type<uint>(j) + as_type<uint>(2)))) {
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ case 1: {
+ switch(k) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.spvasm b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.spvasm
new file mode 100644
index 0000000..b32b253
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.spvasm
@@ -0,0 +1,96 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 48
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %k "k"
+ OpName %i "i"
+ OpName %j "j"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %k = OpVariable %_ptr_Function_int Function %6
+ %i = OpVariable %_ptr_Function_int Function %6
+ %j = OpVariable %_ptr_Function_int Function %6
+ OpStore %k %6
+ OpStore %i %6
+ OpBranch %10
+ %10 = OpLabel
+ OpLoopMerge %11 %12 None
+ OpBranch %13
+ %13 = OpLabel
+ %15 = OpLoad %int %i
+ %17 = OpSLessThan %bool %15 %int_2
+ %14 = OpLogicalNot %bool %17
+ OpSelectionMerge %19 None
+ OpBranchConditional %14 %20 %19
+ %20 = OpLabel
+ OpBranch %11
+ %19 = OpLabel
+ %22 = OpLoad %int %i
+ OpSelectionMerge %21 None
+ OpSwitch %22 %23 0 %24
+ %24 = OpLabel
+ OpStore %j %6
+ OpBranch %26
+ %26 = OpLabel
+ OpLoopMerge %27 %28 None
+ OpBranch %29
+ %29 = OpLabel
+ %31 = OpLoad %int %j
+ %32 = OpSLessThan %bool %31 %int_2
+ %30 = OpLogicalNot %bool %32
+ OpSelectionMerge %33 None
+ OpBranchConditional %30 %34 %33
+ %34 = OpLabel
+ OpBranch %27
+ %33 = OpLabel
+ %36 = OpLoad %int %j
+ OpSelectionMerge %35 None
+ OpSwitch %36 %37 0 %38 1 %39
+ %38 = OpLabel
+ OpBranch %28
+ %39 = OpLabel
+ %41 = OpLoad %int %k
+ OpSelectionMerge %40 None
+ OpSwitch %41 %42 0 %43
+ %43 = OpLabel
+ OpBranch %28
+ %42 = OpLabel
+ OpBranch %40
+ %40 = OpLabel
+ OpBranch %35
+ %37 = OpLabel
+ OpBranch %35
+ %35 = OpLabel
+ OpBranch %28
+ %28 = OpLabel
+ %44 = OpLoad %int %j
+ %45 = OpIAdd %int %44 %int_2
+ OpStore %j %45
+ OpBranch %26
+ %27 = OpLabel
+ OpBranch %12
+ %23 = OpLabel
+ OpBranch %21
+ %21 = OpLabel
+ OpBranch %12
+ %12 = OpLabel
+ %46 = OpLoad %int %i
+ %47 = OpIAdd %int %46 %int_2
+ OpStore %i %47
+ OpBranch %10
+ %11 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.wgsl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.wgsl
new file mode 100644
index 0000000..7c7cdb9
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.wgsl
@@ -0,0 +1,31 @@
+@compute @workgroup_size(1)
+fn main() {
+ var k = 0;
+ for(var i = 0; (i < 2); i += 2) {
+ switch(i) {
+ case 0: {
+ for(var j = 0; (j < 2); j += 2) {
+ switch(j) {
+ case 0: {
+ continue;
+ }
+ case 1: {
+ switch(k) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+ default: {
+ }
+ }
+ }
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl b/test/tint/loops/nested_loop_switch_switch.wgsl
new file mode 100644
index 0000000..9949f96
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl
@@ -0,0 +1,19 @@
+@compute @workgroup_size(1)
+fn main() {
+ var j = 0;
+ for (var i = 0; i < 2; i += 2) {
+ switch(i) {
+ case 0: {
+ switch(j) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.dxc.hlsl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..160d4d6
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.dxc.hlsl
@@ -0,0 +1,34 @@
+[numthreads(1, 1, 1)]
+void main() {
+ int j = 0;
+ bool tint_continue = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ switch(j) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.fxc.hlsl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..160d4d6
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.fxc.hlsl
@@ -0,0 +1,34 @@
+[numthreads(1, 1, 1)]
+void main() {
+ int j = 0;
+ bool tint_continue = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ switch(j) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.glsl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.glsl
new file mode 100644
index 0000000..ec32b25
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.glsl
@@ -0,0 +1,32 @@
+#version 310 es
+
+void tint_symbol() {
+ int j = 0;
+ {
+ for(int i = 0; (i < 2); i = (i + 2)) {
+ switch(i) {
+ case 0: {
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl
new file mode 100644
index 0000000..55f4436
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.msl
@@ -0,0 +1,27 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ int j = 0;
+ for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(2)))) {
+ switch(i) {
+ case 0: {
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.spvasm b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.spvasm
new file mode 100644
index 0000000..f6add1f
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.spvasm
@@ -0,0 +1,63 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 31
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %j "j"
+ OpName %i "i"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %j = OpVariable %_ptr_Function_int Function %6
+ %i = OpVariable %_ptr_Function_int Function %6
+ OpStore %j %6
+ OpStore %i %6
+ OpBranch %10
+ %10 = OpLabel
+ OpLoopMerge %11 %12 None
+ OpBranch %13
+ %13 = OpLabel
+ %15 = OpLoad %int %i
+ %17 = OpSLessThan %bool %15 %int_2
+ %14 = OpLogicalNot %bool %17
+ OpSelectionMerge %19 None
+ OpBranchConditional %14 %20 %19
+ %20 = OpLabel
+ OpBranch %11
+ %19 = OpLabel
+ %22 = OpLoad %int %i
+ OpSelectionMerge %21 None
+ OpSwitch %22 %23 0 %24
+ %24 = OpLabel
+ %26 = OpLoad %int %j
+ OpSelectionMerge %25 None
+ OpSwitch %26 %27 0 %28
+ %28 = OpLabel
+ OpBranch %12
+ %27 = OpLabel
+ OpBranch %25
+ %25 = OpLabel
+ OpBranch %21
+ %23 = OpLabel
+ OpBranch %21
+ %21 = OpLabel
+ OpBranch %12
+ %12 = OpLabel
+ %29 = OpLoad %int %i
+ %30 = OpIAdd %int %29 %int_2
+ OpStore %i %30
+ OpBranch %10
+ %11 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.wgsl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.wgsl
new file mode 100644
index 0000000..4d8f604
--- /dev/null
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.wgsl
@@ -0,0 +1,19 @@
+@compute @workgroup_size(1)
+fn main() {
+ var j = 0;
+ for(var i = 0; (i < 2); i += 2) {
+ switch(i) {
+ case 0: {
+ switch(j) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/single_continue.wgsl b/test/tint/loops/single_continue.wgsl
new file mode 100644
index 0000000..d59d2fa
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl
@@ -0,0 +1,12 @@
+@compute @workgroup_size(1)
+fn main() {
+ for (var i = 0; i < 2; i += 1) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}
diff --git a/test/tint/loops/single_continue.wgsl.expected.dxc.hlsl b/test/tint/loops/single_continue.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..5955f1e
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl.expected.dxc.hlsl
@@ -0,0 +1,22 @@
+[numthreads(1, 1, 1)]
+void main() {
+ bool tint_continue = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 1)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/single_continue.wgsl.expected.fxc.hlsl b/test/tint/loops/single_continue.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..5955f1e
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl.expected.fxc.hlsl
@@ -0,0 +1,22 @@
+[numthreads(1, 1, 1)]
+void main() {
+ bool tint_continue = false;
+ {
+ for(int i = 0; (i < 2); i = (i + 1)) {
+ tint_continue = false;
+ switch(i) {
+ case 0: {
+ tint_continue = true;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ }
+ }
+ return;
+}
diff --git a/test/tint/loops/single_continue.wgsl.expected.glsl b/test/tint/loops/single_continue.wgsl.expected.glsl
new file mode 100644
index 0000000..79afd54
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl.expected.glsl
@@ -0,0 +1,23 @@
+#version 310 es
+
+void tint_symbol() {
+ {
+ for(int i = 0; (i < 2); i = (i + 1)) {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ }
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol();
+ return;
+}
diff --git a/test/tint/loops/single_continue.wgsl.expected.msl b/test/tint/loops/single_continue.wgsl.expected.msl
new file mode 100644
index 0000000..3ce3ba5
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl.expected.msl
@@ -0,0 +1,18 @@
+#include <metal_stdlib>
+
+using namespace metal;
+kernel void tint_symbol() {
+ for(int i = 0; (i < 2); i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ return;
+}
+
diff --git a/test/tint/loops/single_continue.wgsl.expected.spvasm b/test/tint/loops/single_continue.wgsl.expected.spvasm
new file mode 100644
index 0000000..7b4bed2
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl.expected.spvasm
@@ -0,0 +1,53 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 27
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %i "i"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %6 = OpConstantNull %int
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_2 = OpConstant %int 2
+ %bool = OpTypeBool
+ %int_1 = OpConstant %int 1
+ %main = OpFunction %void None %1
+ %4 = OpLabel
+ %i = OpVariable %_ptr_Function_int Function %6
+ OpStore %i %6
+ OpBranch %9
+ %9 = OpLabel
+ OpLoopMerge %10 %11 None
+ OpBranch %12
+ %12 = OpLabel
+ %14 = OpLoad %int %i
+ %16 = OpSLessThan %bool %14 %int_2
+ %13 = OpLogicalNot %bool %16
+ OpSelectionMerge %18 None
+ OpBranchConditional %13 %19 %18
+ %19 = OpLabel
+ OpBranch %10
+ %18 = OpLabel
+ %21 = OpLoad %int %i
+ OpSelectionMerge %20 None
+ OpSwitch %21 %22 0 %23
+ %23 = OpLabel
+ OpBranch %11
+ %22 = OpLabel
+ OpBranch %20
+ %20 = OpLabel
+ OpBranch %11
+ %11 = OpLabel
+ %24 = OpLoad %int %i
+ %26 = OpIAdd %int %24 %int_1
+ OpStore %i %26
+ OpBranch %9
+ %10 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/loops/single_continue.wgsl.expected.wgsl b/test/tint/loops/single_continue.wgsl.expected.wgsl
new file mode 100644
index 0000000..6554849
--- /dev/null
+++ b/test/tint/loops/single_continue.wgsl.expected.wgsl
@@ -0,0 +1,12 @@
+@compute @workgroup_size(1)
+fn main() {
+ for(var i = 0; (i < 2); i += 1) {
+ switch(i) {
+ case 0: {
+ continue;
+ }
+ default: {
+ }
+ }
+ }
+}