• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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