HLSL: workaround FXC error "continue cannot be used in a switch"
Added a new transform::RemoveContinueInSwitch that replaces continue
statements in switch cases with setting a bool variable, and checking if
the variable is set after the switch to continue.
Bug: tint:1080
Change-Id: I3c0a6c790e1bb612fac3f927a4bd5beb2d0d4ed1
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/84960
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index a2541bd..0d52704 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -471,6 +471,8 @@
"transform/promote_initializers_to_const_var.h",
"transform/promote_side_effects_to_decl.cc",
"transform/promote_side_effects_to_decl.h",
+ "transform/remove_continue_in_switch.cc",
+ "transform/remove_continue_in_switch.h",
"transform/remove_phonies.cc",
"transform/remove_phonies.h",
"transform/remove_unreachable_statements.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 0a3ce1c..30e2322 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -351,6 +351,8 @@
transform/promote_side_effects_to_decl.h
transform/remove_phonies.cc
transform/remove_phonies.h
+ transform/remove_continue_in_switch.cc
+ transform/remove_continue_in_switch.h
transform/remove_unreachable_statements.cc
transform/remove_unreachable_statements.h
transform/renamer.cc
@@ -1027,6 +1029,7 @@
transform/num_workgroups_from_uniform_test.cc
transform/promote_initializers_to_const_var_test.cc
transform/promote_side_effects_to_decl_test.cc
+ transform/remove_continue_in_switch_test.cc
transform/remove_phonies_test.cc
transform/remove_unreachable_statements_test.cc
transform/renamer_test.cc
diff --git a/src/tint/transform/remove_continue_in_switch.cc b/src/tint/transform/remove_continue_in_switch.cc
new file mode 100644
index 0000000..9ee05c0
--- /dev/null
+++ b/src/tint/transform/remove_continue_in_switch.cc
@@ -0,0 +1,145 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/transform/remove_continue_in_switch.h"
+
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+#include "src/tint/ast/continue_statement.h"
+#include "src/tint/ast/switch_statement.h"
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/block_statement.h"
+#include "src/tint/sem/for_loop_statement.h"
+#include "src/tint/sem/loop_statement.h"
+#include "src/tint/sem/switch_statement.h"
+#include "src/tint/transform/utils/get_insertion_point.h"
+#include "src/tint/utils/map.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::transform::RemoveContinueInSwitch);
+
+namespace tint::transform {
+namespace {
+
+class State {
+ private:
+ CloneContext& ctx;
+ ProgramBuilder& b;
+ const sem::Info& sem;
+
+ // Map of switch statement to 'tint_continue' variable.
+ std::unordered_map<const ast::SwitchStatement*, Symbol>
+ switch_to_cont_var_name;
+
+ // If `cont` is within a switch statement within a loop, returns a pointer to
+ // that switch statement.
+ static const ast::SwitchStatement* GetParentSwitchInLoop(
+ const sem::Info& sem,
+ const ast::ContinueStatement* cont) {
+ // Find whether first parent is a switch or a loop
+ auto* sem_stmt = sem.Get(cont);
+ auto* sem_parent =
+ sem_stmt->FindFirstParent<sem::SwitchStatement, sem::LoopBlockStatement,
+ sem::ForLoopStatement>();
+ if (!sem_parent) {
+ return nullptr;
+ }
+ return sem_parent->Declaration()->As<ast::SwitchStatement>();
+ }
+
+ public:
+ /// Constructor
+ /// @param ctx_in the context
+ explicit State(CloneContext& ctx_in)
+ : ctx(ctx_in), b(*ctx_in.dst), sem(ctx_in.src->Sem()) {}
+
+ /// Returns true if this transform should be run for the given program
+ static bool ShouldRun(const Program* program) {
+ for (auto* node : program->ASTNodes().Objects()) {
+ auto* stmt = node->As<ast::ContinueStatement>();
+ if (!stmt) {
+ continue;
+ }
+ if (GetParentSwitchInLoop(program->Sem(), stmt)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Runs the transform
+ void Run() {
+ for (auto* node : ctx.src->ASTNodes().Objects()) {
+ auto* cont = node->As<ast::ContinueStatement>();
+ if (!cont) {
+ continue;
+ }
+
+ // If first parent is not a switch within a loop, skip
+ auto* switch_stmt = GetParentSwitchInLoop(sem, cont);
+ if (!switch_stmt) {
+ continue;
+ }
+
+ auto cont_var_name =
+ tint::utils::GetOrCreate(switch_to_cont_var_name, switch_stmt, [&]() {
+ // Create and insert 'var tint_continue : bool = false;' before the
+ // switch.
+ auto var_name = b.Symbols().New("tint_continue");
+ auto* decl = b.Decl(b.Var(var_name, b.ty.bool_(), b.Expr(false)));
+ auto ip = utils::GetInsertionPoint(ctx, switch_stmt);
+ ctx.InsertBefore(ip.first->Declaration()->statements, ip.second,
+ decl);
+
+ // Create and insert 'if (tint_continue) { continue; }' after
+ // switch.
+ auto* if_stmt = b.If(b.Expr(var_name), b.Block(b.Continue()));
+ ctx.InsertAfter(ip.first->Declaration()->statements, ip.second,
+ if_stmt);
+
+ // Return the new var name
+ return var_name;
+ });
+
+ // Replace 'continue;' with '{ tint_continue = true; break; }'
+ auto* new_stmt = b.Block( //
+ b.Assign(b.Expr(cont_var_name), true), //
+ b.Break());
+
+ ctx.Replace(cont, new_stmt);
+ }
+
+ ctx.Clone();
+ }
+};
+
+} // namespace
+
+RemoveContinueInSwitch::RemoveContinueInSwitch() = default;
+RemoveContinueInSwitch::~RemoveContinueInSwitch() = default;
+
+bool RemoveContinueInSwitch::ShouldRun(const Program* program,
+ const DataMap& /*data*/) const {
+ return State::ShouldRun(program);
+}
+
+void RemoveContinueInSwitch::Run(CloneContext& ctx,
+ const DataMap&,
+ DataMap&) const {
+ State state(ctx);
+ state.Run();
+}
+
+} // namespace tint::transform
diff --git a/src/tint/transform/remove_continue_in_switch.h b/src/tint/transform/remove_continue_in_switch.h
new file mode 100644
index 0000000..f875660
--- /dev/null
+++ b/src/tint/transform/remove_continue_in_switch.h
@@ -0,0 +1,55 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_TRANSFORM_REMOVE_CONTINUE_IN_SWITCH_H_
+#define SRC_TINT_TRANSFORM_REMOVE_CONTINUE_IN_SWITCH_H_
+
+#include "src/tint/transform/transform.h"
+
+namespace tint::transform {
+
+/// This transform replaces continue statements in switch cases with setting a
+/// bool variable, and checking if the variable is set after the switch to
+/// continue. It is necessary to work around FXC "error X3708: continue cannot
+/// be used in a switch". See crbug.com/tint/1080.
+class RemoveContinueInSwitch
+ : public Castable<RemoveContinueInSwitch, Transform> {
+ public:
+ /// Constructor
+ RemoveContinueInSwitch();
+
+ /// Destructor
+ ~RemoveContinueInSwitch() override;
+
+ protected:
+ /// @param program the program to inspect
+ /// @param data optional extra transform-specific input data
+ /// @returns true if this transform should be run for the given program
+ bool ShouldRun(const Program* program,
+ const DataMap& data = {}) const override;
+
+ /// Runs the transform using the CloneContext built for transforming a
+ /// program. Run() is responsible for calling Clone() on the CloneContext.
+ /// @param ctx the CloneContext primed with the input program and
+ /// ProgramBuilder
+ /// @param inputs optional extra transform-specific input data
+ /// @param outputs optional extra transform-specific output data
+ void Run(CloneContext& ctx,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
+};
+
+} // namespace tint::transform
+
+#endif // SRC_TINT_TRANSFORM_REMOVE_CONTINUE_IN_SWITCH_H_
diff --git a/src/tint/transform/remove_continue_in_switch_test.cc b/src/tint/transform/remove_continue_in_switch_test.cc
new file mode 100644
index 0000000..cd485b0
--- /dev/null
+++ b/src/tint/transform/remove_continue_in_switch_test.cc
@@ -0,0 +1,565 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/transform/remove_continue_in_switch.h"
+#include "src/tint/transform/test_helper.h"
+
+namespace tint {
+namespace transform {
+namespace {
+
+using RemoveContinueInSwitchTest = TransformTest;
+
+TEST_F(RemoveContinueInSwitchTest, ShouldRun_True) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ loop {
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+}
+)";
+
+ EXPECT_TRUE(ShouldRun<RemoveContinueInSwitch>(src));
+}
+
+TEST_F(RemoveContinueInSwitchTest, ShouldRunEmptyModule_False) {
+ auto* src = "";
+
+ EXPECT_FALSE(ShouldRun<RemoveContinueInSwitch>(src));
+}
+
+TEST_F(RemoveContinueInSwitchTest, ShouldRunContinueNotInSwitch_False) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ loop {
+ switch(i) {
+ case 0: {
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ if (true) {
+ continue;
+ }
+ break;
+ }
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<RemoveContinueInSwitch>(src));
+}
+
+TEST_F(RemoveContinueInSwitchTest, ShouldRunContinueInLoopInSwitch_False) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ switch(i) {
+ case 0: {
+ loop {
+ if (true) {
+ continue;
+ }
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+)";
+
+ EXPECT_FALSE(ShouldRun<RemoveContinueInSwitch>(src));
+}
+
+TEST_F(RemoveContinueInSwitchTest, EmptyModule) {
+ auto* src = "";
+ auto* expect = src;
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RemoveContinueInSwitchTest, SingleContinue) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker2 = 0;
+ break;
+
+ continuing {
+ let marker3 = 0;
+ }
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ var tint_continue : bool = false;
+ switch(i) {
+ case 0: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ let marker2 = 0;
+ break;
+
+ continuing {
+ let marker3 = 0;
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RemoveContinueInSwitchTest, MultipleContinues) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ case 1: {
+ continue;
+ break;
+ }
+ case 2: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker2 = 0;
+ break;
+
+ continuing {
+ let marker3 = 0;
+ }
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ var tint_continue : bool = false;
+ switch(i) {
+ case 0: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ case 1: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ case 2: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ let marker2 = 0;
+ break;
+
+ continuing {
+ let marker3 = 0;
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RemoveContinueInSwitchTest, MultipleSwitch) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker2 = 0;
+
+ let marker3 = 0;
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker4 = 0;
+
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ var tint_continue : bool = false;
+ switch(i) {
+ case 0: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ let marker2 = 0;
+ let marker3 = 0;
+ var tint_continue_1 : bool = false;
+ switch(i) {
+ case 0: {
+ {
+ tint_continue_1 = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue_1) {
+ continue;
+ }
+ let marker4 = 0;
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RemoveContinueInSwitchTest, NestedLoopSwitch) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ switch(i) {
+ case 0: {
+ var j = 0;
+ loop {
+ let marker3 = 0;
+ switch(j) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker4 = 0;
+ break;
+ }
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker2 = 0;
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var i = 0;
+ loop {
+ let marker1 = 0;
+ var tint_continue_1 : bool = false;
+ switch(i) {
+ case 0: {
+ var j = 0;
+ loop {
+ let marker3 = 0;
+ var tint_continue : bool = false;
+ switch(j) {
+ case 0: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ let marker4 = 0;
+ break;
+ }
+ {
+ tint_continue_1 = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue_1) {
+ continue;
+ }
+ let marker2 = 0;
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RemoveContinueInSwitchTest, ExtraScopes) {
+ auto* src = R"(
+fn f() {
+ var i = 0;
+ var a = true;
+ var b = true;
+ var c = true;
+ var d = true;
+ loop {
+ if (a) {
+ if (b) {
+ let marker1 = 0;
+ switch(i) {
+ case 0: {
+ if (c) {
+ if (d) {
+ continue;
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker2 = 0;
+ break;
+ }
+ }
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ var i = 0;
+ var a = true;
+ var b = true;
+ var c = true;
+ var d = true;
+ loop {
+ if (a) {
+ if (b) {
+ let marker1 = 0;
+ var tint_continue : bool = false;
+ switch(i) {
+ case 0: {
+ if (c) {
+ if (d) {
+ {
+ tint_continue = true;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ let marker2 = 0;
+ break;
+ }
+ }
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(RemoveContinueInSwitchTest, ForLoop) {
+ auto* src = R"(
+fn f() {
+ for (var i = 0; i < 4; i = i + 1) {
+ let marker1 = 0;
+ switch(i) {
+ case 0: {
+ continue;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ let marker2 = 0;
+ break;
+ }
+}
+)";
+
+ auto* expect = R"(
+fn f() {
+ for(var i = 0; (i < 4); i = (i + 1)) {
+ let marker1 = 0;
+ var tint_continue : bool = false;
+ switch(i) {
+ case 0: {
+ {
+ tint_continue = true;
+ break;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ if (tint_continue) {
+ continue;
+ }
+ let marker2 = 0;
+ break;
+ }
+}
+)";
+
+ DataMap data;
+ auto got = Run<RemoveContinueInSwitch>(src, data);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace
+} // namespace transform
+} // namespace tint
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index e384156..9ed948d 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -59,6 +59,7 @@
#include "src/tint/transform/num_workgroups_from_uniform.h"
#include "src/tint/transform/promote_initializers_to_const_var.h"
#include "src/tint/transform/promote_side_effects_to_decl.h"
+#include "src/tint/transform/remove_continue_in_switch.h"
#include "src/tint/transform/remove_phonies.h"
#include "src/tint/transform/simplify_pointers.h"
#include "src/tint/transform/unshadow.h"
@@ -210,6 +211,8 @@
manager.Add<transform::CalculateArrayLength>();
manager.Add<transform::PromoteInitializersToConstVar>();
+ manager.Add<transform::RemoveContinueInSwitch>();
+
manager.Add<transform::AddEmptyEntryPoint>();
data.Add<transform::CanonicalizeEntryPointIO::Config>(
diff --git a/test/tint/BUILD.gn b/test/tint/BUILD.gn
index 6bdd527..3588b08 100644
--- a/test/tint/BUILD.gn
+++ b/test/tint/BUILD.gn
@@ -329,6 +329,7 @@
"../../src/tint/transform/num_workgroups_from_uniform_test.cc",
"../../src/tint/transform/promote_initializers_to_const_var_test.cc",
"../../src/tint/transform/promote_side_effects_to_decl_test.cc",
+ "../../src/tint/transform/remove_continue_in_switch_test.cc",
"../../src/tint/transform/remove_phonies_test.cc",
"../../src/tint/transform/remove_unreachable_statements_test.cc",
"../../src/tint/transform/renamer_test.cc",
diff --git a/test/tint/loops/continue_in_switch.wgsl.expected.hlsl b/test/tint/loops/continue_in_switch.wgsl.expected.hlsl
index 773a4ce..3aa81e3 100644
--- a/test/tint/loops/continue_in_switch.wgsl.expected.hlsl
+++ b/test/tint/loops/continue_in_switch.wgsl.expected.hlsl
@@ -1,20 +1,24 @@
-SKIP: FAILED
-
[numthreads(1, 1, 1)]
void f() {
{
[loop] for(int i = 0; (i < 4); i = (i + 1)) {
+ bool tint_continue = false;
switch(i) {
case 0: {
- continue;
+ {
+ tint_continue = true;
+ break;
+ }
break;
}
default: {
break;
}
}
+ if (tint_continue) {
+ continue;
+ }
}
}
return;
}
-C:\src\tint\test\Shader@0x000001A817AB3700(7,11-19): error X3708: continue cannot be used in a switch
diff --git a/test/tint/vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.spvasm.expected.hlsl b/test/tint/vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.spvasm.expected.hlsl
deleted file mode 100644
index 8be27ab..0000000
--- a/test/tint/vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.spvasm.expected.hlsl
+++ /dev/null
@@ -1,122 +0,0 @@
-SKIP: FAILED
-
-warning: code is unreachable
-cbuffer cbuffer_x_6 : register(b0, space0) {
- uint4 x_6[1];
-};
-static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-void main_1() {
- int data[10] = (int[10])0;
- int x_40 = 0;
- int x_40_phi = 0;
- int x_11_phi = 0;
- const int x_7 = data[1];
- const int x_10 = ((1 < x_7) ? 2 : 1);
- x_40_phi = 1;
- x_11_phi = x_10;
- [loop] while (true) {
- int x_54 = 0;
- int x_41 = 0;
- int x_41_phi = 0;
- x_40 = x_40_phi;
- const int x_11 = x_11_phi;
- if ((x_11 < 3)) {
- } else {
- break;
- }
- int x_54_phi = 0;
- const int x_8 = (x_11 + 1);
- const float x_47 = asfloat(x_6[0].x);
- x_54_phi = x_40;
- switch(int(x_47)) {
- case 78: {
- x_GLF_color = float4(1.0f, 1.0f, 1.0f, 1.0f);
- /* fallthrough */
- {
- x_54_phi = asint((x_40 + asint(1)));
- /* fallthrough */
- }
- {
- x_54 = x_54_phi;
- x_41_phi = x_54;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- }
- break;
- }
- case 19: {
- x_54_phi = asint((x_40 + asint(1)));
- /* fallthrough */
- {
- x_54 = x_54_phi;
- x_41_phi = x_54;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- }
- break;
- }
- case 23:
- case 38: {
- x_54 = x_54_phi;
- x_41_phi = x_54;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- break;
- }
- default: {
- x_41_phi = x_40;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- break;
- }
- }
- x_41_phi = 0;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- }
- data[x_40] = 1;
- x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
- return;
-}
-
-struct main_out {
- float4 x_GLF_color_1;
-};
-struct tint_symbol {
- float4 x_GLF_color_1 : SV_Target0;
-};
-
-main_out main_inner() {
- main_1();
- const main_out tint_symbol_2 = {x_GLF_color};
- return tint_symbol_2;
-}
-
-tint_symbol main() {
- const main_out inner_result = main_inner();
- tint_symbol wrapper_result = (tint_symbol)0;
- wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
- return wrapper_result;
-}
-C:\src\tint\test\Shader@0x0000022C8EAC8720(45,11-19): error X3708: continue cannot be used in a switch
-
diff --git a/test/tint/vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.wgsl.expected.hlsl b/test/tint/vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.wgsl.expected.hlsl
deleted file mode 100644
index 58fea7f..0000000
--- a/test/tint/vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.wgsl.expected.hlsl
+++ /dev/null
@@ -1,125 +0,0 @@
-SKIP: FAILED
-
-vk-gl-cts/graphicsfuzz/call-if-while-switch/0-opt.wgsl:52:5 warning: code is unreachable
- x_41_phi = 0;
- ^^^^^^^^
-
-cbuffer cbuffer_x_6 : register(b0, space0) {
- uint4 x_6[1];
-};
-static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-void main_1() {
- int data[10] = (int[10])0;
- int x_40 = 0;
- int x_40_phi = 0;
- int x_11_phi = 0;
- const int x_7 = data[1];
- const int x_10 = ((1 < x_7) ? 2 : 1);
- x_40_phi = 1;
- x_11_phi = x_10;
- [loop] while (true) {
- int x_54 = 0;
- int x_41 = 0;
- int x_41_phi = 0;
- x_40 = x_40_phi;
- const int x_11 = x_11_phi;
- if ((x_11 < 3)) {
- } else {
- break;
- }
- int x_54_phi = 0;
- const int x_8 = (x_11 + 1);
- const float x_47 = asfloat(x_6[0].x);
- x_54_phi = x_40;
- switch(int(x_47)) {
- case 78: {
- x_GLF_color = float4(1.0f, 1.0f, 1.0f, 1.0f);
- /* fallthrough */
- {
- x_54_phi = asint((x_40 + asint(1)));
- /* fallthrough */
- }
- {
- x_54 = x_54_phi;
- x_41_phi = x_54;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- }
- break;
- }
- case 19: {
- x_54_phi = asint((x_40 + asint(1)));
- /* fallthrough */
- {
- x_54 = x_54_phi;
- x_41_phi = x_54;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- }
- break;
- }
- case 23:
- case 38: {
- x_54 = x_54_phi;
- x_41_phi = x_54;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- break;
- }
- default: {
- x_41_phi = x_40;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- continue;
- break;
- }
- }
- x_41_phi = 0;
- {
- x_41 = x_41_phi;
- x_40_phi = x_41;
- x_11_phi = x_8;
- }
- }
- data[x_40] = 1;
- x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
- return;
-}
-
-struct main_out {
- float4 x_GLF_color_1;
-};
-struct tint_symbol {
- float4 x_GLF_color_1 : SV_Target0;
-};
-
-main_out main_inner() {
- main_1();
- const main_out tint_symbol_2 = {x_GLF_color};
- return tint_symbol_2;
-}
-
-tint_symbol main() {
- const main_out inner_result = main_inner();
- tint_symbol wrapper_result = (tint_symbol)0;
- wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
- return wrapper_result;
-}
-C:\src\tint\test\Shader@0x0000025D82F36130(45,11-19): error X3708: continue cannot be used in a switch
-
diff --git a/test/tint/vk-gl-cts/graphicsfuzz/cov-x86-isel-lowering-negative-left-shift/0-opt.spvasm.expected.hlsl b/test/tint/vk-gl-cts/graphicsfuzz/cov-x86-isel-lowering-negative-left-shift/0-opt.spvasm.expected.hlsl
deleted file mode 100644
index dafcc86..0000000
--- a/test/tint/vk-gl-cts/graphicsfuzz/cov-x86-isel-lowering-negative-left-shift/0-opt.spvasm.expected.hlsl
+++ /dev/null
@@ -1,124 +0,0 @@
-SKIP: FAILED
-
-cbuffer cbuffer_x_6 : register(b1, space0) {
- uint4 x_6[3];
-};
-cbuffer cbuffer_x_9 : register(b0, space0) {
- uint4 x_9[4];
-};
-static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-void main_1() {
- float A[2] = (float[2])0;
- int i = 0;
- int j = 0;
- bool x_101 = false;
- bool x_102_phi = false;
- const float x_39 = asfloat(x_6[1].x);
- A[0] = x_39;
- const float x_42 = asfloat(x_6[1].x);
- A[1] = x_42;
- const uint scalar_offset = ((16u * uint(0))) / 4;
- const int x_45 = asint(x_9[scalar_offset / 4][scalar_offset % 4]);
- i = x_45;
- [loop] while (true) {
- const int x_50 = i;
- const int x_52 = asint(x_9[3].x);
- if ((x_50 < x_52)) {
- } else {
- break;
- }
- const uint scalar_offset_1 = ((16u * uint(0))) / 4;
- const int x_56 = asint(x_9[scalar_offset_1 / 4][scalar_offset_1 % 4]);
- j = x_56;
- [loop] while (true) {
- const int x_61 = j;
- const int x_63 = asint(x_9[2].x);
- if ((x_61 < x_63)) {
- } else {
- break;
- }
- switch(j) {
- case 1: {
- const int x_78 = i;
- const uint scalar_offset_2 = ((16u * uint(0))) / 4;
- const float x_80 = asfloat(x_6[scalar_offset_2 / 4][scalar_offset_2 % 4]);
- A[x_78] = x_80;
- break;
- }
- case 0: {
- if ((-2147483648 < i)) {
- {
- j = (j + 1);
- }
- continue;
- }
- const int x_74 = i;
- const float x_76 = asfloat(x_6[2].x);
- A[x_74] = x_76;
- break;
- }
- default: {
- break;
- }
- }
- {
- j = (j + 1);
- }
- }
- {
- i = (i + 1);
- }
- }
- const uint scalar_offset_3 = ((16u * uint(0))) / 4;
- const int x_87 = asint(x_9[scalar_offset_3 / 4][scalar_offset_3 % 4]);
- const float x_89 = A[x_87];
- const uint scalar_offset_4 = ((16u * uint(0))) / 4;
- const float x_91 = asfloat(x_6[scalar_offset_4 / 4][scalar_offset_4 % 4]);
- const bool x_92 = (x_89 == x_91);
- x_102_phi = x_92;
- if (x_92) {
- const int x_96 = asint(x_9[1].x);
- const float x_98 = A[x_96];
- const uint scalar_offset_5 = ((16u * uint(0))) / 4;
- const float x_100 = asfloat(x_6[scalar_offset_5 / 4][scalar_offset_5 % 4]);
- x_101 = (x_98 == x_100);
- x_102_phi = x_101;
- }
- if (x_102_phi) {
- const int x_107 = asint(x_9[1].x);
- const uint scalar_offset_6 = ((16u * uint(0))) / 4;
- const int x_110 = asint(x_9[scalar_offset_6 / 4][scalar_offset_6 % 4]);
- const uint scalar_offset_7 = ((16u * uint(0))) / 4;
- const int x_113 = asint(x_9[scalar_offset_7 / 4][scalar_offset_7 % 4]);
- const int x_116 = asint(x_9[1].x);
- x_GLF_color = float4(float(x_107), float(x_110), float(x_113), float(x_116));
- } else {
- const int x_120 = asint(x_9[1].x);
- const float x_121 = float(x_120);
- x_GLF_color = float4(x_121, x_121, x_121, x_121);
- }
- return;
-}
-
-struct main_out {
- float4 x_GLF_color_1;
-};
-struct tint_symbol {
- float4 x_GLF_color_1 : SV_Target0;
-};
-
-main_out main_inner() {
- main_1();
- const main_out tint_symbol_3 = {x_GLF_color};
- return tint_symbol_3;
-}
-
-tint_symbol main() {
- const main_out inner_result = main_inner();
- tint_symbol wrapper_result = (tint_symbol)0;
- wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
- return wrapper_result;
-}
-C:\src\tint\test\Shader@0x000001CAF72F14F0(52,13-21): error X3708: continue cannot be used in a switch
-
diff --git a/test/tint/vk-gl-cts/graphicsfuzz/cov-x86-isel-lowering-negative-left-shift/0-opt.wgsl.expected.hlsl b/test/tint/vk-gl-cts/graphicsfuzz/cov-x86-isel-lowering-negative-left-shift/0-opt.wgsl.expected.hlsl
deleted file mode 100644
index 4843bc4..0000000
--- a/test/tint/vk-gl-cts/graphicsfuzz/cov-x86-isel-lowering-negative-left-shift/0-opt.wgsl.expected.hlsl
+++ /dev/null
@@ -1,124 +0,0 @@
-SKIP: FAILED
-
-cbuffer cbuffer_x_6 : register(b1, space0) {
- uint4 x_6[3];
-};
-cbuffer cbuffer_x_9 : register(b0, space0) {
- uint4 x_9[4];
-};
-static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-void main_1() {
- float A[2] = (float[2])0;
- int i = 0;
- int j = 0;
- bool x_101 = false;
- bool x_102_phi = false;
- const float x_39 = asfloat(x_6[1].x);
- A[0] = x_39;
- const float x_42 = asfloat(x_6[1].x);
- A[1] = x_42;
- const uint scalar_offset = ((16u * uint(0))) / 4;
- const int x_45 = asint(x_9[scalar_offset / 4][scalar_offset % 4]);
- i = x_45;
- [loop] while (true) {
- const int x_50 = i;
- const int x_52 = asint(x_9[3].x);
- if ((x_50 < x_52)) {
- } else {
- break;
- }
- const uint scalar_offset_1 = ((16u * uint(0))) / 4;
- const int x_56 = asint(x_9[scalar_offset_1 / 4][scalar_offset_1 % 4]);
- j = x_56;
- [loop] while (true) {
- const int x_61 = j;
- const int x_63 = asint(x_9[2].x);
- if ((x_61 < x_63)) {
- } else {
- break;
- }
- switch(j) {
- case 1: {
- const int x_78 = i;
- const uint scalar_offset_2 = ((16u * uint(0))) / 4;
- const float x_80 = asfloat(x_6[scalar_offset_2 / 4][scalar_offset_2 % 4]);
- A[x_78] = x_80;
- break;
- }
- case 0: {
- if ((-2147483648 < i)) {
- {
- j = (j + 1);
- }
- continue;
- }
- const int x_74 = i;
- const float x_76 = asfloat(x_6[2].x);
- A[x_74] = x_76;
- break;
- }
- default: {
- break;
- }
- }
- {
- j = (j + 1);
- }
- }
- {
- i = (i + 1);
- }
- }
- const uint scalar_offset_3 = ((16u * uint(0))) / 4;
- const int x_87 = asint(x_9[scalar_offset_3 / 4][scalar_offset_3 % 4]);
- const float x_89 = A[x_87];
- const uint scalar_offset_4 = ((16u * uint(0))) / 4;
- const float x_91 = asfloat(x_6[scalar_offset_4 / 4][scalar_offset_4 % 4]);
- const bool x_92 = (x_89 == x_91);
- x_102_phi = x_92;
- if (x_92) {
- const int x_96 = asint(x_9[1].x);
- const float x_98 = A[x_96];
- const uint scalar_offset_5 = ((16u * uint(0))) / 4;
- const float x_100 = asfloat(x_6[scalar_offset_5 / 4][scalar_offset_5 % 4]);
- x_101 = (x_98 == x_100);
- x_102_phi = x_101;
- }
- if (x_102_phi) {
- const int x_107 = asint(x_9[1].x);
- const uint scalar_offset_6 = ((16u * uint(0))) / 4;
- const int x_110 = asint(x_9[scalar_offset_6 / 4][scalar_offset_6 % 4]);
- const uint scalar_offset_7 = ((16u * uint(0))) / 4;
- const int x_113 = asint(x_9[scalar_offset_7 / 4][scalar_offset_7 % 4]);
- const int x_116 = asint(x_9[1].x);
- x_GLF_color = float4(float(x_107), float(x_110), float(x_113), float(x_116));
- } else {
- const int x_120 = asint(x_9[1].x);
- const float x_121 = float(x_120);
- x_GLF_color = float4(x_121, x_121, x_121, x_121);
- }
- return;
-}
-
-struct main_out {
- float4 x_GLF_color_1;
-};
-struct tint_symbol {
- float4 x_GLF_color_1 : SV_Target0;
-};
-
-main_out main_inner() {
- main_1();
- const main_out tint_symbol_3 = {x_GLF_color};
- return tint_symbol_3;
-}
-
-tint_symbol main() {
- const main_out inner_result = main_inner();
- tint_symbol wrapper_result = (tint_symbol)0;
- wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
- return wrapper_result;
-}
-C:\src\tint\test\Shader@0x0000027536C22E40(52,13-21): error X3708: continue cannot be used in a switch
-
diff --git a/test/tint/vk-gl-cts/graphicsfuzz/switch-loop-switch-if/0-opt.spvasm.expected.hlsl b/test/tint/vk-gl-cts/graphicsfuzz/switch-loop-switch-if/0-opt.spvasm.expected.hlsl
deleted file mode 100644
index 65bba35..0000000
--- a/test/tint/vk-gl-cts/graphicsfuzz/switch-loop-switch-if/0-opt.spvasm.expected.hlsl
+++ /dev/null
@@ -1,86 +0,0 @@
-SKIP: FAILED
-
-cbuffer cbuffer_x_6 : register(b0, space0) {
- uint4 x_6[1];
-};
-static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-void main_1() {
- int i = 0;
- const float x_51 = asfloat(x_6[0].x);
- i = int(x_51);
- switch(i) {
- case 0: {
- [loop] while (true) {
- i = (i + 1);
- switch(i) {
- case 2: {
- i = (i + 5);
- break;
- }
- case 1: {
- {
- if ((i > 200)) {
- } else {
- break;
- }
- }
- continue;
- break;
- }
- default: {
- i = (i + 7);
- break;
- }
- }
- {
- if ((i > 200)) {
- } else {
- break;
- }
- }
- }
- if ((i > 100)) {
- i = (i - 2);
- break;
- }
- /* fallthrough */
- {
- i = (i - 3);
- }
- break;
- }
- default: {
- i = (i - 3);
- break;
- }
- }
- if ((i == -2)) {
- x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
- } else {
- x_GLF_color = float4(0.0f, 0.0f, 0.0f, 1.0f);
- }
- return;
-}
-
-struct main_out {
- float4 x_GLF_color_1;
-};
-struct tint_symbol {
- float4 x_GLF_color_1 : SV_Target0;
-};
-
-main_out main_inner() {
- main_1();
- const main_out tint_symbol_2 = {x_GLF_color};
- return tint_symbol_2;
-}
-
-tint_symbol main() {
- const main_out inner_result = main_inner();
- tint_symbol wrapper_result = (tint_symbol)0;
- wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
- return wrapper_result;
-}
-C:\src\tint\test\Shader@0x0000013B8CBD6FE0(26,13-21): error X3708: continue cannot be used in a switch
-
diff --git a/test/tint/vk-gl-cts/graphicsfuzz/switch-loop-switch-if/0-opt.wgsl.expected.hlsl b/test/tint/vk-gl-cts/graphicsfuzz/switch-loop-switch-if/0-opt.wgsl.expected.hlsl
deleted file mode 100644
index 7516688..0000000
--- a/test/tint/vk-gl-cts/graphicsfuzz/switch-loop-switch-if/0-opt.wgsl.expected.hlsl
+++ /dev/null
@@ -1,86 +0,0 @@
-SKIP: FAILED
-
-cbuffer cbuffer_x_6 : register(b0, space0) {
- uint4 x_6[1];
-};
-static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
-
-void main_1() {
- int i = 0;
- const float x_51 = asfloat(x_6[0].x);
- i = int(x_51);
- switch(i) {
- case 0: {
- [loop] while (true) {
- i = (i + 1);
- switch(i) {
- case 2: {
- i = (i + 5);
- break;
- }
- case 1: {
- {
- if ((i > 200)) {
- } else {
- break;
- }
- }
- continue;
- break;
- }
- default: {
- i = (i + 7);
- break;
- }
- }
- {
- if ((i > 200)) {
- } else {
- break;
- }
- }
- }
- if ((i > 100)) {
- i = (i - 2);
- break;
- }
- /* fallthrough */
- {
- i = (i - 3);
- }
- break;
- }
- default: {
- i = (i - 3);
- break;
- }
- }
- if ((i == -2)) {
- x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
- } else {
- x_GLF_color = float4(0.0f, 0.0f, 0.0f, 1.0f);
- }
- return;
-}
-
-struct main_out {
- float4 x_GLF_color_1;
-};
-struct tint_symbol {
- float4 x_GLF_color_1 : SV_Target0;
-};
-
-main_out main_inner() {
- main_1();
- const main_out tint_symbol_2 = {x_GLF_color};
- return tint_symbol_2;
-}
-
-tint_symbol main() {
- const main_out inner_result = main_inner();
- tint_symbol wrapper_result = (tint_symbol)0;
- wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
- return wrapper_result;
-}
-C:\src\tint\test\Shader@0x0000019C85DE9DB0(26,13-21): error X3708: continue cannot be used in a switch
-