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/loop_to_for_loop.h"
16
17 #include "src/transform/test_helper.h"
18
19 namespace tint {
20 namespace transform {
21 namespace {
22
23 using LoopToForLoopTest = TransformTest;
24
TEST_F(LoopToForLoopTest,EmptyModule)25 TEST_F(LoopToForLoopTest, EmptyModule) {
26 auto* src = "";
27 auto* expect = "";
28
29 auto got = Run<LoopToForLoop>(src);
30
31 EXPECT_EQ(expect, str(got));
32 }
33
TEST_F(LoopToForLoopTest,IfBreak)34 TEST_F(LoopToForLoopTest, IfBreak) {
35 auto* src = R"(
36 fn f() {
37 var i : i32;
38 i = 0;
39 loop {
40 if (i > 15) {
41 break;
42 }
43
44 ignore(123);
45
46 continuing {
47 i = i + 1;
48 }
49 }
50 }
51 )";
52
53 auto* expect = R"(
54 fn f() {
55 var i : i32;
56 i = 0;
57 for(; !((i > 15)); i = (i + 1)) {
58 ignore(123);
59 }
60 }
61 )";
62
63 auto got = Run<LoopToForLoop>(src);
64
65 EXPECT_EQ(expect, str(got));
66 }
67
TEST_F(LoopToForLoopTest,IfElseBreak)68 TEST_F(LoopToForLoopTest, IfElseBreak) {
69 auto* src = R"(
70 fn f() {
71 var i : i32;
72 i = 0;
73 loop {
74 if (i < 15) {
75 } else {
76 break;
77 }
78
79 ignore(123);
80
81 continuing {
82 i = i + 1;
83 }
84 }
85 }
86 )";
87
88 auto* expect = R"(
89 fn f() {
90 var i : i32;
91 i = 0;
92 for(; (i < 15); i = (i + 1)) {
93 ignore(123);
94 }
95 }
96 )";
97
98 auto got = Run<LoopToForLoop>(src);
99
100 EXPECT_EQ(expect, str(got));
101 }
102
TEST_F(LoopToForLoopTest,Nested)103 TEST_F(LoopToForLoopTest, Nested) {
104 auto* src = R"(
105 let N = 16u;
106
107 fn f() {
108 var i : u32 = 0u;
109 loop {
110 if (i >= N) {
111 break;
112 }
113 {
114 var j : u32 = 0u;
115 loop {
116 if (j >= N) {
117 break;
118 }
119
120 ignore(i);
121 ignore(j);
122
123 continuing {
124 j = (j + 1u);
125 }
126 }
127 }
128
129 continuing {
130 i = (i + 1u);
131 }
132 }
133 }
134 )";
135
136 auto* expect = R"(
137 let N = 16u;
138
139 fn f() {
140 var i : u32 = 0u;
141 for(; !((i >= N)); i = (i + 1u)) {
142 {
143 var j : u32 = 0u;
144 for(; !((j >= N)); j = (j + 1u)) {
145 ignore(i);
146 ignore(j);
147 }
148 }
149 }
150 }
151 )";
152
153 auto got = Run<LoopToForLoop>(src);
154
155 EXPECT_EQ(expect, str(got));
156 }
157
TEST_F(LoopToForLoopTest,NoTransform_IfMultipleStmts)158 TEST_F(LoopToForLoopTest, NoTransform_IfMultipleStmts) {
159 auto* src = R"(
160 fn f() {
161 var i : i32;
162 i = 0;
163 loop {
164 if ((i < 15)) {
165 ignore(i);
166 break;
167 }
168 ignore(123);
169
170 continuing {
171 i = (i + 1);
172 }
173 }
174 }
175 )";
176
177 auto* expect = src;
178
179 auto got = Run<LoopToForLoop>(src);
180
181 EXPECT_EQ(expect, str(got));
182 }
183
TEST_F(LoopToForLoopTest,NoTransform_IfElseMultipleStmts)184 TEST_F(LoopToForLoopTest, NoTransform_IfElseMultipleStmts) {
185 auto* src = R"(
186 fn f() {
187 var i : i32;
188 i = 0;
189 loop {
190 if ((i < 15)) {
191 } else {
192 ignore(i);
193 break;
194 }
195 ignore(123);
196
197 continuing {
198 i = (i + 1);
199 }
200 }
201 }
202 )";
203
204 auto* expect = src;
205
206 auto got = Run<LoopToForLoop>(src);
207
208 EXPECT_EQ(expect, str(got));
209 }
210
TEST_F(LoopToForLoopTest,NoTransform_ContinuingIsCompound)211 TEST_F(LoopToForLoopTest, NoTransform_ContinuingIsCompound) {
212 auto* src = R"(
213 fn f() {
214 var i : i32;
215 i = 0;
216 loop {
217 if ((i < 15)) {
218 break;
219 }
220 ignore(123);
221
222 continuing {
223 if (false) {
224 }
225 }
226 }
227 }
228 )";
229
230 auto* expect = src;
231
232 auto got = Run<LoopToForLoop>(src);
233
234 EXPECT_EQ(expect, str(got));
235 }
236
TEST_F(LoopToForLoopTest,NoTransform_ContinuingMultipleStmts)237 TEST_F(LoopToForLoopTest, NoTransform_ContinuingMultipleStmts) {
238 auto* src = R"(
239 fn f() {
240 var i : i32;
241 i = 0;
242 loop {
243 if ((i < 15)) {
244 break;
245 }
246 ignore(123);
247
248 continuing {
249 i = (i + 1);
250 ignore(i);
251 }
252 }
253 }
254 )";
255
256 auto* expect = src;
257
258 auto got = Run<LoopToForLoop>(src);
259
260 EXPECT_EQ(expect, str(got));
261 }
262
TEST_F(LoopToForLoopTest,NoTransform_ContinuingUsesVarDeclInLoopBody)263 TEST_F(LoopToForLoopTest, NoTransform_ContinuingUsesVarDeclInLoopBody) {
264 auto* src = R"(
265 fn f() {
266 var i : i32;
267 i = 0;
268 loop {
269 if ((i < 15)) {
270 break;
271 }
272 var j : i32;
273
274 continuing {
275 i = (i + j);
276 }
277 }
278 }
279 )";
280
281 auto* expect = src;
282
283 auto got = Run<LoopToForLoop>(src);
284
285 EXPECT_EQ(expect, str(got));
286 }
287
288 } // namespace
289 } // namespace transform
290 } // namespace tint
291