1 // 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/transform/remove_unreachable_statements.h"
16
17 #include "src/transform/test_helper.h"
18
19 namespace tint {
20 namespace transform {
21 namespace {
22
23 using RemoveUnreachableStatementsTest = TransformTest;
24
TEST_F(RemoveUnreachableStatementsTest,EmptyModule)25 TEST_F(RemoveUnreachableStatementsTest, EmptyModule) {
26 auto* src = "";
27 auto* expect = "";
28
29 auto got = Run<RemoveUnreachableStatements>(src);
30
31 EXPECT_EQ(expect, str(got));
32 }
33
TEST_F(RemoveUnreachableStatementsTest,Return)34 TEST_F(RemoveUnreachableStatementsTest, Return) {
35 auto* src = R"(
36 fn f() {
37 return;
38 var remove_me = 1;
39 if (true) {
40 var remove_me_too = 1;
41 }
42 }
43 )";
44
45 auto* expect = R"(
46 fn f() {
47 return;
48 }
49 )";
50
51 auto got = Run<RemoveUnreachableStatements>(src);
52
53 EXPECT_EQ(expect, str(got));
54 }
55
TEST_F(RemoveUnreachableStatementsTest,NestedReturn)56 TEST_F(RemoveUnreachableStatementsTest, NestedReturn) {
57 auto* src = R"(
58 fn f() {
59 {
60 {
61 return;
62 }
63 }
64 var remove_me = 1;
65 if (true) {
66 var remove_me_too = 1;
67 }
68 }
69 )";
70
71 auto* expect = R"(
72 fn f() {
73 {
74 {
75 return;
76 }
77 }
78 }
79 )";
80
81 auto got = Run<RemoveUnreachableStatements>(src);
82
83 EXPECT_EQ(expect, str(got));
84 }
85
TEST_F(RemoveUnreachableStatementsTest,Discard)86 TEST_F(RemoveUnreachableStatementsTest, Discard) {
87 auto* src = R"(
88 fn f() {
89 discard;
90 var remove_me = 1;
91 if (true) {
92 var remove_me_too = 1;
93 }
94 }
95 )";
96
97 auto* expect = R"(
98 fn f() {
99 discard;
100 }
101 )";
102
103 auto got = Run<RemoveUnreachableStatements>(src);
104
105 EXPECT_EQ(expect, str(got));
106 }
107
TEST_F(RemoveUnreachableStatementsTest,NestedDiscard)108 TEST_F(RemoveUnreachableStatementsTest, NestedDiscard) {
109 auto* src = R"(
110 fn f() {
111 {
112 {
113 discard;
114 }
115 }
116 var remove_me = 1;
117 if (true) {
118 var remove_me_too = 1;
119 }
120 }
121 )";
122
123 auto* expect = R"(
124 fn f() {
125 {
126 {
127 discard;
128 }
129 }
130 }
131 )";
132
133 auto got = Run<RemoveUnreachableStatements>(src);
134
135 EXPECT_EQ(expect, str(got));
136 }
137
TEST_F(RemoveUnreachableStatementsTest,CallToFuncWithDiscard)138 TEST_F(RemoveUnreachableStatementsTest, CallToFuncWithDiscard) {
139 auto* src = R"(
140 fn DISCARD() {
141 discard;
142 }
143
144 fn f() {
145 DISCARD();
146 var remove_me = 1;
147 if (true) {
148 var remove_me_too = 1;
149 }
150 }
151 )";
152
153 auto* expect = R"(
154 fn DISCARD() {
155 discard;
156 }
157
158 fn f() {
159 DISCARD();
160 }
161 )";
162
163 auto got = Run<RemoveUnreachableStatements>(src);
164
165 EXPECT_EQ(expect, str(got));
166 }
167
TEST_F(RemoveUnreachableStatementsTest,CallToFuncWithIfDiscard)168 TEST_F(RemoveUnreachableStatementsTest, CallToFuncWithIfDiscard) {
169 auto* src = R"(
170 fn DISCARD() {
171 if (true) {
172 discard;
173 }
174 }
175
176 fn f() {
177 DISCARD();
178 var preserve_me = 1;
179 if (true) {
180 var preserve_me_too = 1;
181 }
182 }
183 )";
184
185 auto* expect = src;
186
187 auto got = Run<RemoveUnreachableStatements>(src);
188
189 EXPECT_EQ(expect, str(got));
190 }
191
TEST_F(RemoveUnreachableStatementsTest,IfDiscardElseDiscard)192 TEST_F(RemoveUnreachableStatementsTest, IfDiscardElseDiscard) {
193 auto* src = R"(
194 fn f() {
195 if (true) {
196 discard;
197 } else {
198 discard;
199 }
200 var remove_me = 1;
201 if (true) {
202 var remove_me_too = 1;
203 }
204 }
205 )";
206
207 auto* expect = R"(
208 fn f() {
209 if (true) {
210 discard;
211 } else {
212 discard;
213 }
214 }
215 )";
216
217 auto got = Run<RemoveUnreachableStatements>(src);
218
219 EXPECT_EQ(expect, str(got));
220 }
221
TEST_F(RemoveUnreachableStatementsTest,IfDiscardElseReturn)222 TEST_F(RemoveUnreachableStatementsTest, IfDiscardElseReturn) {
223 auto* src = R"(
224 fn f() {
225 if (true) {
226 discard;
227 } else {
228 return;
229 }
230 var remove_me = 1;
231 if (true) {
232 var remove_me_too = 1;
233 }
234 }
235 )";
236
237 auto* expect = R"(
238 fn f() {
239 if (true) {
240 discard;
241 } else {
242 return;
243 }
244 }
245 )";
246
247 auto got = Run<RemoveUnreachableStatements>(src);
248
249 EXPECT_EQ(expect, str(got));
250 }
251
TEST_F(RemoveUnreachableStatementsTest,IfDiscard)252 TEST_F(RemoveUnreachableStatementsTest, IfDiscard) {
253 auto* src = R"(
254 fn f() {
255 if (true) {
256 discard;
257 }
258 var preserve_me = 1;
259 if (true) {
260 var preserve_me_too = 1;
261 }
262 }
263 )";
264
265 auto* expect = src;
266
267 auto got = Run<RemoveUnreachableStatements>(src);
268
269 EXPECT_EQ(expect, str(got));
270 }
271
TEST_F(RemoveUnreachableStatementsTest,IfReturn)272 TEST_F(RemoveUnreachableStatementsTest, IfReturn) {
273 auto* src = R"(
274 fn f() {
275 if (true) {
276 return;
277 }
278 var preserve_me = 1;
279 if (true) {
280 var preserve_me_too = 1;
281 }
282 }
283 )";
284
285 auto* expect = src;
286
287 auto got = Run<RemoveUnreachableStatements>(src);
288
289 EXPECT_EQ(expect, str(got));
290 }
291
TEST_F(RemoveUnreachableStatementsTest,IfElseDiscard)292 TEST_F(RemoveUnreachableStatementsTest, IfElseDiscard) {
293 auto* src = R"(
294 fn f() {
295 if (true) {
296 } else {
297 discard;
298 }
299 var preserve_me = 1;
300 if (true) {
301 var preserve_me_too = 1;
302 }
303 }
304 )";
305
306 auto* expect = src;
307
308 auto got = Run<RemoveUnreachableStatements>(src);
309
310 EXPECT_EQ(expect, str(got));
311 }
312
TEST_F(RemoveUnreachableStatementsTest,IfElseReturn)313 TEST_F(RemoveUnreachableStatementsTest, IfElseReturn) {
314 auto* src = R"(
315 fn f() {
316 if (true) {
317 } else {
318 return;
319 }
320 var preserve_me = 1;
321 if (true) {
322 var preserve_me_too = 1;
323 }
324 }
325 )";
326
327 auto* expect = src;
328
329 auto got = Run<RemoveUnreachableStatements>(src);
330
331 EXPECT_EQ(expect, str(got));
332 }
333
TEST_F(RemoveUnreachableStatementsTest,LoopWithNoBreak)334 TEST_F(RemoveUnreachableStatementsTest, LoopWithNoBreak) {
335 auto* src = R"(
336 fn f() {
337 loop {
338 var a = 1;
339 continuing {
340 var b = 2;
341 }
342 }
343 var remove_me = 1;
344 if (true) {
345 var remove_me_too = 1;
346 }
347 }
348 )";
349
350 auto* expect = R"(
351 fn f() {
352 loop {
353 var a = 1;
354
355 continuing {
356 var b = 2;
357 }
358 }
359 }
360 )";
361
362 auto got = Run<RemoveUnreachableStatements>(src);
363
364 EXPECT_EQ(expect, str(got));
365 }
366
TEST_F(RemoveUnreachableStatementsTest,LoopWithConditionalBreak)367 TEST_F(RemoveUnreachableStatementsTest, LoopWithConditionalBreak) {
368 auto* src = R"(
369 fn f() {
370 loop {
371 var a = 1;
372 if (true) {
373 break;
374 }
375
376 continuing {
377 var b = 2;
378 }
379 }
380 var preserve_me = 1;
381 if (true) {
382 var preserve_me_too = 1;
383 }
384 }
385 )";
386
387 auto* expect = src;
388
389 auto got = Run<RemoveUnreachableStatements>(src);
390
391 EXPECT_EQ(expect, str(got));
392 }
393
TEST_F(RemoveUnreachableStatementsTest,LoopWithConditionalBreakInContinuing)394 TEST_F(RemoveUnreachableStatementsTest, LoopWithConditionalBreakInContinuing) {
395 auto* src = R"(
396 fn f() {
397 loop {
398
399 continuing {
400 if (true) {
401 break;
402 }
403 }
404 }
405 var preserve_me = 1;
406 if (true) {
407 var preserve_me_too = 1;
408 }
409 }
410 )";
411
412 auto* expect = src;
413
414 auto got = Run<RemoveUnreachableStatements>(src);
415
416 EXPECT_EQ(expect, str(got));
417 }
418
TEST_F(RemoveUnreachableStatementsTest,SwitchDefaultDiscard)419 TEST_F(RemoveUnreachableStatementsTest, SwitchDefaultDiscard) {
420 auto* src = R"(
421 fn f() {
422 switch(1) {
423 default: {
424 discard;
425 }
426 }
427 var remove_me = 1;
428 if (true) {
429 var remove_me_too = 1;
430 }
431 }
432 )";
433
434 auto* expect = R"(
435 fn f() {
436 switch(1) {
437 default: {
438 discard;
439 }
440 }
441 }
442 )";
443
444 auto got = Run<RemoveUnreachableStatements>(src);
445
446 EXPECT_EQ(expect, str(got));
447 }
448
TEST_F(RemoveUnreachableStatementsTest,SwitchCaseReturnDefaultDiscard)449 TEST_F(RemoveUnreachableStatementsTest, SwitchCaseReturnDefaultDiscard) {
450 auto* src = R"(
451 fn f() {
452 switch(1) {
453 case 0: {
454 return;
455 }
456 default: {
457 discard;
458 }
459 }
460 var remove_me = 1;
461 if (true) {
462 var remove_me_too = 1;
463 }
464 }
465 )";
466
467 auto* expect = R"(
468 fn f() {
469 switch(1) {
470 case 0: {
471 return;
472 }
473 default: {
474 discard;
475 }
476 }
477 }
478 )";
479
480 auto got = Run<RemoveUnreachableStatements>(src);
481
482 EXPECT_EQ(expect, str(got));
483 }
484
TEST_F(RemoveUnreachableStatementsTest,SwitchCaseBreakDefaultDiscard)485 TEST_F(RemoveUnreachableStatementsTest, SwitchCaseBreakDefaultDiscard) {
486 auto* src = R"(
487 fn f() {
488 switch(1) {
489 case 0: {
490 break;
491 }
492 default: {
493 discard;
494 }
495 }
496 var preserve_me = 1;
497 if (true) {
498 var preserve_me_too = 1;
499 }
500 }
501 )";
502
503 auto* expect = src;
504
505 auto got = Run<RemoveUnreachableStatements>(src);
506
507 EXPECT_EQ(expect, str(got));
508 }
509
TEST_F(RemoveUnreachableStatementsTest,SwitchCaseReturnDefaultBreak)510 TEST_F(RemoveUnreachableStatementsTest, SwitchCaseReturnDefaultBreak) {
511 auto* src = R"(
512 fn f() {
513 switch(1) {
514 case 0: {
515 return;
516 }
517 default: {
518 break;
519 }
520 }
521 var preserve_me = 1;
522 if (true) {
523 var preserve_me_too = 1;
524 }
525 }
526 )";
527
528 auto* expect = src;
529
530 auto got = Run<RemoveUnreachableStatements>(src);
531
532 EXPECT_EQ(expect, str(got));
533 }
534
535 } // namespace
536 } // namespace transform
537 } // namespace tint
538