[ir][msl] Emit switch instructions
Add support for the ir switch instructions.
Bug: tint:1967
Change-Id: I838527ea04cea2bfeef0b5c528f58166a0d6339e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/162264
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 4bf5b2f..dbe51d4 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -44,6 +44,7 @@
#include "src/tint/lang/core/ir/discard.h"
#include "src/tint/lang/core/ir/exit_if.h"
#include "src/tint/lang/core/ir/exit_loop.h"
+#include "src/tint/lang/core/ir/exit_switch.h"
#include "src/tint/lang/core/ir/ice.h"
#include "src/tint/lang/core/ir/if.h"
#include "src/tint/lang/core/ir/let.h"
@@ -53,6 +54,7 @@
#include "src/tint/lang/core/ir/next_iteration.h"
#include "src/tint/lang/core/ir/return.h"
#include "src/tint/lang/core/ir/store.h"
+#include "src/tint/lang/core/ir/switch.h"
#include "src/tint/lang/core/ir/unreachable.h"
#include "src/tint/lang/core/ir/user_call.h"
#include "src/tint/lang/core/ir/validator.h"
@@ -282,6 +284,8 @@
[&](core::ir::NextIteration*) { /* do nothing */ }, //
[&](core::ir::BreakIf* b) { EmitBreakIf(b); }, //
[&](core::ir::ExitLoop*) { EmitExitLoop(); }, //
+ [&](core::ir::ExitSwitch*) { EmitExitSwitch(); }, //
+ [&](core::ir::Switch* s) { EmitSwitch(s); }, //
[&](core::ir::Bitcast*) { MaybeEmitInstruction(inst); }, //
[&](core::ir::Unary*) { MaybeEmitInstruction(inst); }, //
@@ -520,6 +524,39 @@
Line() << "}";
}
+ void EmitExitSwitch() { Line() << "break;"; }
+
+ void EmitSwitch(core::ir::Switch* s) {
+ {
+ auto out = Line();
+ out << "switch(";
+ EmitValue(out, s->Condition());
+ out << ") {";
+ }
+ {
+ ScopedIndent blk(current_buffer_);
+ for (auto& case_ : s->Cases()) {
+ for (auto& sel : case_.selectors) {
+ if (sel.IsDefault()) {
+ Line() << "default:";
+ } else {
+ auto out = Line();
+ out << "case ";
+ EmitValue(out, sel.val);
+ out << ":";
+ }
+ }
+ Line() << "{";
+ {
+ ScopedIndent ci(current_buffer_);
+ EmitBlock(case_.block);
+ }
+ Line() << "}";
+ }
+ }
+ Line() << "}";
+ }
+
/// Emit an if instruction
/// @param if_ the if instruction
void EmitIf(core::ir::If* if_) {
diff --git a/test/tint/loops/continue_in_switch.wgsl.expected.ir.msl b/test/tint/loops/continue_in_switch.wgsl.expected.ir.msl
index cdbf128..88c3be7 100644
--- a/test/tint/loops/continue_in_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/continue_in_switch.wgsl.expected.ir.msl
@@ -1,9 +1,27 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void f() {
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 4)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ i = (i + 1);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 1);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/multiple_continues.wgsl.expected.ir.msl b/test/tint/loops/multiple_continues.wgsl.expected.ir.msl
index cdbf128..de48573 100644
--- a/test/tint/loops/multiple_continues.wgsl.expected.ir.msl
+++ b/test/tint/loops/multiple_continues.wgsl.expected.ir.msl
@@ -1,9 +1,37 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ i = (i + 1);
+ continue;
+ }
+ case 1:
+ {
+ i = (i + 1);
+ continue;
+ }
+ case 2:
+ {
+ i = (i + 1);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 1);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/multiple_switch.wgsl.expected.ir.msl b/test/tint/loops/multiple_switch.wgsl.expected.ir.msl
index cdbf128..6a761f7 100644
--- a/test/tint/loops/multiple_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/multiple_switch.wgsl.expected.ir.msl
@@ -1,9 +1,39 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ int i = 0;
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ i = (i + 1);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ switch(i) {
+ case 0:
+ {
+ i = (i + 1);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 1);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl
index cdbf128..8921168 100644
--- a/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_loop_switch.wgsl.expected.ir.msl
@@ -1,9 +1,38 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ {
+ int j = 0;
+ while(true) {
+ if ((j < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ j = (j + 2);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ j = (j + 2);
+ continue;
+ }
+ }
+ i = (i + 2);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl
index cdbf128..6dbcb48 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_switch_loop_switch.wgsl.expected.ir.msl
@@ -1,9 +1,49 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ {
+ int j = 0;
+ while(true) {
+ if ((j < 2)) {
+ } else {
+ break;
+ }
+ switch(j) {
+ case 0:
+ {
+ j = (j + 2);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ j = (j + 2);
+ continue;
+ }
+ }
+ i = (i + 2);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 2);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl
index cdbf128..2fea1a7 100644
--- a/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_switch_loop_switch_switch.wgsl.expected.ir.msl
@@ -1,9 +1,65 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ int k = 0;
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ {
+ int j = 0;
+ while(true) {
+ if ((j < 2)) {
+ } else {
+ break;
+ }
+ switch(j) {
+ case 0:
+ {
+ j = (j + 2);
+ continue;
+ }
+ case 1:
+ {
+ switch(k) {
+ case 0:
+ {
+ j = (j + 2);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ j = (j + 2);
+ continue;
+ }
+ }
+ i = (i + 2);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 2);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl
index cdbf128..a4f719e 100644
--- a/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl
+++ b/test/tint/loops/nested_loop_switch_switch.wgsl.expected.ir.msl
@@ -1,9 +1,38 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ int j = 0;
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ switch(j) {
+ case 0:
+ {
+ i = (i + 2);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 2);
+ continue;
+ }
+ }
+}
diff --git a/test/tint/loops/single_continue.wgsl.expected.ir.msl b/test/tint/loops/single_continue.wgsl.expected.ir.msl
index cdbf128..573c2b5 100644
--- a/test/tint/loops/single_continue.wgsl.expected.ir.msl
+++ b/test/tint/loops/single_continue.wgsl.expected.ir.msl
@@ -1,9 +1,27 @@
-SKIP: FAILED
+#include <metal_stdlib>
+using namespace metal;
-<dawn>/src/tint/lang/msl/writer/printer/printer.cc:247 internal compiler error: Switch() matched no cases. Type: tint::core::ir::Loop
-********************************************************************
-* The tint shader compiler has encountered an unexpected error. *
-* *
-* Please help us fix this issue by submitting a bug report at *
-* crbug.com/tint with the source program that triggered the bug. *
-********************************************************************
+kernel void tint_symbol() {
+ {
+ int i = 0;
+ while(true) {
+ if ((i < 2)) {
+ } else {
+ break;
+ }
+ switch(i) {
+ case 0:
+ {
+ i = (i + 1);
+ continue;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ i = (i + 1);
+ continue;
+ }
+ }
+}