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>
This commit is contained in:
parent
a9d2f636fb
commit
b349710476
|
@ -471,6 +471,8 @@ libtint_source_set("libtint_core_all_src") {
|
|||
"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",
|
||||
|
|
|
@ -351,6 +351,8 @@ set(TINT_LIB_SRCS
|
|||
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 @@ if(TINT_BUILD_TESTS)
|
|||
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
|
||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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
|
|
@ -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 @@ SanitizedResult Sanitize(
|
|||
manager.Add<transform::CalculateArrayLength>();
|
||||
manager.Add<transform::PromoteInitializersToConstVar>();
|
||||
|
||||
manager.Add<transform::RemoveContinueInSwitch>();
|
||||
|
||||
manager.Add<transform::AddEmptyEntryPoint>();
|
||||
|
||||
data.Add<transform::CanonicalizeEntryPointIO::Config>(
|
||||
|
|
|
@ -329,6 +329,7 @@ tint_unittests_source_set("tint_unittests_transform_src") {
|
|||
"../../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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue