transform: LoopToForLoop - fix bad emission
For loops only support assignments or function calls for the continuing statement. Fixed: tint:1064 Change-Id: I07065b2119e7b9f97ca7e46b1464fd72333ca429 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60212 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
a52324fde1
commit
ed60a9905c
|
@ -89,7 +89,8 @@ void LoopToForLoop::Run(CloneContext& ctx, const DataMap&, DataMap&) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// The continuing block must be empty or contain a single statement
|
||||
// The continuing block must be empty or contain a single, assignment or
|
||||
// function call statement.
|
||||
ast::Statement* continuing = nullptr;
|
||||
if (auto* loop_cont = loop->continuing()) {
|
||||
if (loop_cont->statements().size() != 1) {
|
||||
|
@ -97,6 +98,10 @@ void LoopToForLoop::Run(CloneContext& ctx, const DataMap&, DataMap&) {
|
|||
}
|
||||
|
||||
continuing = loop_cont->statements()[0];
|
||||
if (!continuing
|
||||
->IsAnyOf<ast::AssignmentStatement, ast::CallStatement>()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// And the continuing statement must not use any of the variables declared
|
||||
// in the loop body.
|
||||
|
|
|
@ -208,6 +208,32 @@ fn f() {
|
|||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(LoopToForLoopTest, NoTransform_ContinuingIsCompound) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
var i : i32;
|
||||
i = 0;
|
||||
loop {
|
||||
if ((i < 15)) {
|
||||
break;
|
||||
}
|
||||
ignore(123);
|
||||
|
||||
continuing {
|
||||
if (false) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
auto* expect = src;
|
||||
|
||||
auto got = Run<LoopToForLoop>(src);
|
||||
|
||||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(LoopToForLoopTest, NoTransform_ContinuingMultipleStmts) {
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
loop {
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
continuing {
|
||||
if (true) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
void main() {
|
||||
while (true) {
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (true) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
fragment void tint_symbol() {
|
||||
while (true) {
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (true) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 15
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpName %main "main"
|
||||
%void = OpTypeVoid
|
||||
%1 = OpTypeFunction %void
|
||||
%bool = OpTypeBool
|
||||
%false = OpConstantFalse %bool
|
||||
%true = OpConstantTrue %bool
|
||||
%main = OpFunction %void None %1
|
||||
%4 = OpLabel
|
||||
OpBranch %5
|
||||
%5 = OpLabel
|
||||
OpLoopMerge %6 %7 None
|
||||
OpBranch %8
|
||||
%8 = OpLabel
|
||||
OpSelectionMerge %11 None
|
||||
OpBranchConditional %false %12 %13
|
||||
%12 = OpLabel
|
||||
OpBranch %11
|
||||
%13 = OpLabel
|
||||
OpBranch %6
|
||||
%11 = OpLabel
|
||||
OpBranch %7
|
||||
%7 = OpLabel
|
||||
OpBranchConditional %true %5 %6
|
||||
%6 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,16 @@
|
|||
[[stage(fragment)]]
|
||||
fn main() {
|
||||
loop {
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
continuing {
|
||||
if (true) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +1,50 @@
|
|||
SKIP: FAILED
|
||||
|
||||
|
||||
[[block]]
|
||||
struct buf0 {
|
||||
injectionSwitch : vec2<f32>;
|
||||
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
cbuffer cbuffer_x_7 : register(b0, space0) {
|
||||
uint4 x_7[1];
|
||||
};
|
||||
static float4 gl_FragCoord = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
var<private> x_GLF_color : vec4<f32>;
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> x_7 : buf0;
|
||||
|
||||
var<private> gl_FragCoord : vec4<f32>;
|
||||
|
||||
fn main_1() {
|
||||
var i : i32;
|
||||
var i_1 : i32;
|
||||
var i_2 : i32;
|
||||
x_GLF_color = vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||
void main_1() {
|
||||
int i = 0;
|
||||
int i_1 = 0;
|
||||
int i_2 = 0;
|
||||
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
i = 0;
|
||||
let x_35 : f32 = x_7.injectionSwitch.y;
|
||||
if ((x_35 < 0.0)) {
|
||||
const float x_35 = asfloat(x_7[0].y);
|
||||
if ((x_35 < 0.0f)) {
|
||||
} else {
|
||||
var x_42 : bool;
|
||||
let x_41 : f32 = gl_FragCoord.y;
|
||||
x_42 = (x_41 < -1.0);
|
||||
bool x_42 = false;
|
||||
const float x_41 = gl_FragCoord.y;
|
||||
x_42 = (x_41 < -1.0f);
|
||||
if (x_42) {
|
||||
} else {
|
||||
loop {
|
||||
let x_50 : i32 = i;
|
||||
if ((x_50 >= 256)) {
|
||||
while (true) {
|
||||
if ((i >= 256)) {
|
||||
break;
|
||||
}
|
||||
loop {
|
||||
while (true) {
|
||||
i_1 = 0;
|
||||
loop {
|
||||
let x_58 : i32 = i_1;
|
||||
if ((x_58 < 1)) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (x_42) {
|
||||
i_2 = 0;
|
||||
loop {
|
||||
let x_66 : i32 = i_2;
|
||||
if ((x_66 < 1)) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
continuing {
|
||||
let x_70 : i32 = i_2;
|
||||
i_2 = (x_70 + 1);
|
||||
{
|
||||
for(; (i_1 < 1); i_1 = (i_1 + 1)) {
|
||||
if (x_42) {
|
||||
i_2 = 0;
|
||||
{
|
||||
for(; (i_2 < 1); i_2 = (i_2 + 1)) {
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
|
||||
continuing {
|
||||
let x_72 : i32 = i_1;
|
||||
i_1 = (x_72 + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
continuing {
|
||||
{
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continuing {
|
||||
{
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
|
@ -84,15 +57,20 @@ fn main_1() {
|
|||
}
|
||||
|
||||
struct main_out {
|
||||
[[location(0)]]
|
||||
x_GLF_color_1 : vec4<f32>;
|
||||
float4 x_GLF_color_1;
|
||||
};
|
||||
struct tint_symbol_1 {
|
||||
float4 gl_FragCoord_param : SV_Position;
|
||||
};
|
||||
struct tint_symbol_2 {
|
||||
float4 x_GLF_color_1 : SV_Target0;
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main([[builtin(position)]] gl_FragCoord_param : vec4<f32>) -> main_out {
|
||||
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
||||
const float4 gl_FragCoord_param = tint_symbol.gl_FragCoord_param;
|
||||
gl_FragCoord = gl_FragCoord_param;
|
||||
main_1();
|
||||
return main_out(x_GLF_color);
|
||||
const main_out tint_symbol_3 = {x_GLF_color};
|
||||
const tint_symbol_2 tint_symbol_5 = {tint_symbol_3.x_GLF_color_1};
|
||||
return tint_symbol_5;
|
||||
}
|
||||
|
||||
Failed to generate: error: break statement must be in a loop or switch case
|
||||
|
|
|
@ -1,77 +1,50 @@
|
|||
SKIP: FAILED
|
||||
|
||||
|
||||
[[block]]
|
||||
struct buf0 {
|
||||
injectionSwitch : vec2<f32>;
|
||||
static float4 x_GLF_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
cbuffer cbuffer_x_7 : register(b0, space0) {
|
||||
uint4 x_7[1];
|
||||
};
|
||||
static float4 gl_FragCoord = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
var<private> x_GLF_color : vec4<f32>;
|
||||
|
||||
[[group(0), binding(0)]] var<uniform> x_7 : buf0;
|
||||
|
||||
var<private> gl_FragCoord : vec4<f32>;
|
||||
|
||||
fn main_1() {
|
||||
var i : i32;
|
||||
var i_1 : i32;
|
||||
var i_2 : i32;
|
||||
x_GLF_color = vec4<f32>(1.0, 0.0, 0.0, 1.0);
|
||||
void main_1() {
|
||||
int i = 0;
|
||||
int i_1 = 0;
|
||||
int i_2 = 0;
|
||||
x_GLF_color = float4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
i = 0;
|
||||
let x_35 : f32 = x_7.injectionSwitch.y;
|
||||
if ((x_35 < 0.0)) {
|
||||
const float x_35 = asfloat(x_7[0].y);
|
||||
if ((x_35 < 0.0f)) {
|
||||
} else {
|
||||
var x_42 : bool;
|
||||
let x_41 : f32 = gl_FragCoord.y;
|
||||
x_42 = (x_41 < -1.0);
|
||||
bool x_42 = false;
|
||||
const float x_41 = gl_FragCoord.y;
|
||||
x_42 = (x_41 < -1.0f);
|
||||
if (x_42) {
|
||||
} else {
|
||||
loop {
|
||||
let x_50 : i32 = i;
|
||||
if ((x_50 >= 256)) {
|
||||
while (true) {
|
||||
if ((i >= 256)) {
|
||||
break;
|
||||
}
|
||||
loop {
|
||||
while (true) {
|
||||
i_1 = 0;
|
||||
loop {
|
||||
let x_58 : i32 = i_1;
|
||||
if ((x_58 < 1)) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (x_42) {
|
||||
i_2 = 0;
|
||||
loop {
|
||||
let x_66 : i32 = i_2;
|
||||
if ((x_66 < 1)) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
continuing {
|
||||
let x_70 : i32 = i_2;
|
||||
i_2 = (x_70 + 1);
|
||||
{
|
||||
for(; (i_1 < 1); i_1 = (i_1 + 1)) {
|
||||
if (x_42) {
|
||||
i_2 = 0;
|
||||
{
|
||||
for(; (i_2 < 1); i_2 = (i_2 + 1)) {
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
|
||||
continuing {
|
||||
let x_72 : i32 = i_1;
|
||||
i_1 = (x_72 + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
continuing {
|
||||
{
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
continuing {
|
||||
{
|
||||
if (false) {
|
||||
} else {
|
||||
break;
|
||||
|
@ -84,18 +57,20 @@ fn main_1() {
|
|||
}
|
||||
|
||||
struct main_out {
|
||||
[[location(0)]]
|
||||
x_GLF_color_1 : vec4<f32>;
|
||||
float4 x_GLF_color_1;
|
||||
};
|
||||
struct tint_symbol_1 {
|
||||
float4 gl_FragCoord_param : SV_Position;
|
||||
};
|
||||
struct tint_symbol_2 {
|
||||
float4 x_GLF_color_1 : SV_Target0;
|
||||
};
|
||||
|
||||
[[stage(fragment)]]
|
||||
fn main([[builtin(position)]] gl_FragCoord_param : vec4<f32>) -> main_out {
|
||||
tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
||||
const float4 gl_FragCoord_param = tint_symbol.gl_FragCoord_param;
|
||||
gl_FragCoord = gl_FragCoord_param;
|
||||
main_1();
|
||||
return main_out(x_GLF_color);
|
||||
const main_out tint_symbol_3 = {x_GLF_color};
|
||||
const tint_symbol_2 tint_symbol_5 = {tint_symbol_3.x_GLF_color_1};
|
||||
return tint_symbol_5;
|
||||
}
|
||||
|
||||
Failed to generate: vk-gl-cts/graphicsfuzz/two-nested-do-whiles/0-opt.wgsl:74:13 error: break statement must be in a loop or switch case
|
||||
break;
|
||||
^^^^^
|
||||
|
||||
|
|
Loading…
Reference in New Issue