blob: fa34f56f34fd755f68937bbbf61463ae0ae01383 [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "src/tint/transform/for_loop_to_loop.h"
16
17#include "src/tint/transform/test_helper.h"
18
dan sinclairb5599d32022-04-07 16:55:14 +000019namespace tint::transform {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000020namespace {
21
22using ForLoopToLoopTest = TransformTest;
23
24TEST_F(ForLoopToLoopTest, ShouldRunEmptyModule) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000025 auto* src = R"()";
Ryan Harrisondbc13af2022-02-21 15:19:07 +000026
dan sinclair41e4d9a2022-05-01 14:40:55 +000027 EXPECT_FALSE(ShouldRun<ForLoopToLoop>(src));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000028}
29
30TEST_F(ForLoopToLoopTest, ShouldRunHasForLoop) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000031 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +000032fn f() {
33 for (;;) {
34 break;
35 }
36}
37)";
38
dan sinclair41e4d9a2022-05-01 14:40:55 +000039 EXPECT_TRUE(ShouldRun<ForLoopToLoop>(src));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000040}
41
42TEST_F(ForLoopToLoopTest, EmptyModule) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000043 auto* src = "";
44 auto* expect = src;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000045
dan sinclair41e4d9a2022-05-01 14:40:55 +000046 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000047
dan sinclair41e4d9a2022-05-01 14:40:55 +000048 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000049}
50
51// Test an empty for loop.
52TEST_F(ForLoopToLoopTest, Empty) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000053 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +000054fn f() {
55 for (;;) {
56 break;
57 }
58}
59)";
60
dan sinclair41e4d9a2022-05-01 14:40:55 +000061 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +000062fn f() {
63 loop {
64 break;
65 }
66}
67)";
68
dan sinclair41e4d9a2022-05-01 14:40:55 +000069 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000070
dan sinclair41e4d9a2022-05-01 14:40:55 +000071 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000072}
73
74// Test a for loop with non-empty body.
75TEST_F(ForLoopToLoopTest, Body) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000076 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +000077fn f() {
78 for (;;) {
James Price744d0eb2022-11-09 19:58:59 +000079 return;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000080 }
81}
82)";
83
dan sinclair41e4d9a2022-05-01 14:40:55 +000084 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +000085fn f() {
86 loop {
James Price744d0eb2022-11-09 19:58:59 +000087 return;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000088 }
89}
90)";
91
dan sinclair41e4d9a2022-05-01 14:40:55 +000092 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +000093
dan sinclair41e4d9a2022-05-01 14:40:55 +000094 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000095}
96
97// Test a for loop declaring a variable in the initializer statement.
98TEST_F(ForLoopToLoopTest, InitializerStatementDecl) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000099 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000100fn f() {
101 for (var i: i32;;) {
102 break;
103 }
104}
105)";
106
dan sinclair41e4d9a2022-05-01 14:40:55 +0000107 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000108fn f() {
109 {
110 var i : i32;
111 loop {
112 break;
113 }
114 }
115}
116)";
117
dan sinclair41e4d9a2022-05-01 14:40:55 +0000118 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000119
dan sinclair41e4d9a2022-05-01 14:40:55 +0000120 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000121}
122
123// Test a for loop declaring and initializing a variable in the initializer
124// statement.
125TEST_F(ForLoopToLoopTest, InitializerStatementDeclEqual) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000126 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000127fn f() {
128 for (var i: i32 = 0;;) {
129 break;
130 }
131}
132)";
133
dan sinclair41e4d9a2022-05-01 14:40:55 +0000134 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000135fn f() {
136 {
137 var i : i32 = 0;
138 loop {
139 break;
140 }
141 }
142}
143)";
144
dan sinclair41e4d9a2022-05-01 14:40:55 +0000145 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000146
dan sinclair41e4d9a2022-05-01 14:40:55 +0000147 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000148}
149
150// Test a for loop declaring a const variable in the initializer statement.
151TEST_F(ForLoopToLoopTest, InitializerStatementConstDecl) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000152 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000153fn f() {
154 for (let i: i32 = 0;;) {
155 break;
156 }
157}
158)";
159
dan sinclair41e4d9a2022-05-01 14:40:55 +0000160 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000161fn f() {
162 {
163 let i : i32 = 0;
164 loop {
165 break;
166 }
167 }
168}
169)";
170
dan sinclair41e4d9a2022-05-01 14:40:55 +0000171 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000172
dan sinclair41e4d9a2022-05-01 14:40:55 +0000173 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000174}
175
176// Test a for loop assigning a variable in the initializer statement.
177TEST_F(ForLoopToLoopTest, InitializerStatementAssignment) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000178 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000179fn f() {
180 var i: i32;
181 for (i = 0;;) {
182 break;
183 }
184}
185)";
186
dan sinclair41e4d9a2022-05-01 14:40:55 +0000187 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000188fn f() {
189 var i : i32;
190 {
191 i = 0;
192 loop {
193 break;
194 }
195 }
196}
197)";
198
dan sinclair41e4d9a2022-05-01 14:40:55 +0000199 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000200
dan sinclair41e4d9a2022-05-01 14:40:55 +0000201 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000202}
203
204// Test a for loop calling a function in the initializer statement.
205TEST_F(ForLoopToLoopTest, InitializerStatementFuncCall) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000206 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000207fn a(x : i32, y : i32) {
208}
209
210fn f() {
211 var b : i32;
212 var c : i32;
213 for (a(b,c);;) {
214 break;
215 }
216}
217)";
218
dan sinclair41e4d9a2022-05-01 14:40:55 +0000219 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000220fn a(x : i32, y : i32) {
221}
222
223fn f() {
224 var b : i32;
225 var c : i32;
226 {
227 a(b, c);
228 loop {
229 break;
230 }
231 }
232}
233)";
234
dan sinclair41e4d9a2022-05-01 14:40:55 +0000235 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000236
dan sinclair41e4d9a2022-05-01 14:40:55 +0000237 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000238}
239
240// Test a for loop with a break condition
241TEST_F(ForLoopToLoopTest, BreakCondition) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000242 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000243fn f() {
244 for (; 0 == 1;) {
245 }
246}
247)";
248
dan sinclair41e4d9a2022-05-01 14:40:55 +0000249 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000250fn f() {
251 loop {
252 if (!((0 == 1))) {
253 break;
254 }
255 }
256}
257)";
258
dan sinclair41e4d9a2022-05-01 14:40:55 +0000259 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000260
dan sinclair41e4d9a2022-05-01 14:40:55 +0000261 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000262}
263
264// Test a for loop assigning a variable in the continuing statement.
265TEST_F(ForLoopToLoopTest, ContinuingAssignment) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000266 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000267fn f() {
268 var x: i32;
269 for (;;x = 2) {
270 break;
271 }
272}
273)";
274
dan sinclair41e4d9a2022-05-01 14:40:55 +0000275 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000276fn f() {
277 var x : i32;
278 loop {
279 break;
280
281 continuing {
282 x = 2;
283 }
284 }
285}
286)";
287
dan sinclair41e4d9a2022-05-01 14:40:55 +0000288 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000289
dan sinclair41e4d9a2022-05-01 14:40:55 +0000290 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000291}
292
293// Test a for loop calling a function in the continuing statement.
294TEST_F(ForLoopToLoopTest, ContinuingFuncCall) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000295 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000296fn a(x : i32, y : i32) {
297}
298
299fn f() {
300 var b : i32;
301 var c : i32;
302 for (;;a(b,c)) {
303 break;
304 }
305}
306)";
307
dan sinclair41e4d9a2022-05-01 14:40:55 +0000308 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000309fn a(x : i32, y : i32) {
310}
311
312fn f() {
313 var b : i32;
314 var c : i32;
315 loop {
316 break;
317
318 continuing {
319 a(b, c);
320 }
321 }
322}
323)";
324
dan sinclair41e4d9a2022-05-01 14:40:55 +0000325 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000326
dan sinclair41e4d9a2022-05-01 14:40:55 +0000327 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000328}
329
330// Test a for loop with all statements non-empty.
331TEST_F(ForLoopToLoopTest, All) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000332 auto* src = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000333fn f() {
334 var a : i32;
335 for(var i : i32 = 0; i < 4; i = i + 1) {
336 if (a == 0) {
337 continue;
338 }
339 a = a + 2;
340 }
341}
342)";
343
dan sinclair41e4d9a2022-05-01 14:40:55 +0000344 auto* expect = R"(
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000345fn f() {
346 var a : i32;
347 {
348 var i : i32 = 0;
349 loop {
350 if (!((i < 4))) {
351 break;
352 }
353 if ((a == 0)) {
354 continue;
355 }
356 a = (a + 2);
357
358 continuing {
359 i = (i + 1);
360 }
361 }
362 }
363}
364)";
365
dan sinclair41e4d9a2022-05-01 14:40:55 +0000366 auto got = Run<ForLoopToLoop>(src);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000367
dan sinclair41e4d9a2022-05-01 14:40:55 +0000368 EXPECT_EQ(expect, str(got));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000369}
370
371} // namespace
dan sinclairb5599d32022-04-07 16:55:14 +0000372} // namespace tint::transform