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/fold_constants.h"
16
17 #include <memory>
18 #include <utility>
19 #include <vector>
20
21 #include "src/transform/test_helper.h"
22
23 namespace tint {
24 namespace transform {
25 namespace {
26
27 using FoldConstantsTest = TransformTest;
28
TEST_F(FoldConstantsTest,Module_Scalar_NoConversion)29 TEST_F(FoldConstantsTest, Module_Scalar_NoConversion) {
30 auto* src = R"(
31 var<private> a : i32 = i32(123);
32 var<private> b : u32 = u32(123u);
33 var<private> c : f32 = f32(123.0);
34 var<private> d : bool = bool(true);
35
36 fn f() {
37 }
38 )";
39
40 auto* expect = R"(
41 var<private> a : i32 = 123;
42
43 var<private> b : u32 = 123u;
44
45 var<private> c : f32 = 123.0;
46
47 var<private> d : bool = true;
48
49 fn f() {
50 }
51 )";
52
53 auto got = Run<FoldConstants>(src);
54
55 EXPECT_EQ(expect, str(got));
56 }
57
TEST_F(FoldConstantsTest,Module_Scalar_Conversion)58 TEST_F(FoldConstantsTest, Module_Scalar_Conversion) {
59 auto* src = R"(
60 var<private> a : i32 = i32(123.0);
61 var<private> b : u32 = u32(123);
62 var<private> c : f32 = f32(123u);
63 var<private> d : bool = bool(123);
64
65 fn f() {
66 }
67 )";
68
69 auto* expect = R"(
70 var<private> a : i32 = 123;
71
72 var<private> b : u32 = 123u;
73
74 var<private> c : f32 = 123.0;
75
76 var<private> d : bool = true;
77
78 fn f() {
79 }
80 )";
81
82 auto got = Run<FoldConstants>(src);
83
84 EXPECT_EQ(expect, str(got));
85 }
86
TEST_F(FoldConstantsTest,Module_Scalar_MultipleConversions)87 TEST_F(FoldConstantsTest, Module_Scalar_MultipleConversions) {
88 auto* src = R"(
89 var<private> a : i32 = i32(u32(f32(u32(i32(123.0)))));
90 var<private> b : u32 = u32(i32(f32(i32(u32(123)))));
91 var<private> c : f32 = f32(u32(i32(u32(f32(123u)))));
92 var<private> d : bool = bool(i32(f32(i32(u32(123)))));
93
94 fn f() {
95 }
96 )";
97
98 auto* expect = R"(
99 var<private> a : i32 = 123;
100
101 var<private> b : u32 = 123u;
102
103 var<private> c : f32 = 123.0;
104
105 var<private> d : bool = true;
106
107 fn f() {
108 }
109 )";
110
111 auto got = Run<FoldConstants>(src);
112
113 EXPECT_EQ(expect, str(got));
114 }
115
TEST_F(FoldConstantsTest,Module_Vector_NoConversion)116 TEST_F(FoldConstantsTest, Module_Vector_NoConversion) {
117 auto* src = R"(
118 var<private> a : vec3<i32> = vec3<i32>(123);
119 var<private> b : vec3<u32> = vec3<u32>(123u);
120 var<private> c : vec3<f32> = vec3<f32>(123.0);
121 var<private> d : vec3<bool> = vec3<bool>(true);
122
123 fn f() {
124 }
125 )";
126
127 auto* expect = R"(
128 var<private> a : vec3<i32> = vec3<i32>(123);
129
130 var<private> b : vec3<u32> = vec3<u32>(123u);
131
132 var<private> c : vec3<f32> = vec3<f32>(123.0);
133
134 var<private> d : vec3<bool> = vec3<bool>(true);
135
136 fn f() {
137 }
138 )";
139
140 auto got = Run<FoldConstants>(src);
141
142 EXPECT_EQ(expect, str(got));
143 }
144
TEST_F(FoldConstantsTest,Module_Vector_Conversion)145 TEST_F(FoldConstantsTest, Module_Vector_Conversion) {
146 auto* src = R"(
147 var<private> a : vec3<i32> = vec3<i32>(vec3<f32>(123.0));
148 var<private> b : vec3<u32> = vec3<u32>(vec3<i32>(123));
149 var<private> c : vec3<f32> = vec3<f32>(vec3<u32>(123u));
150 var<private> d : vec3<bool> = vec3<bool>(vec3<i32>(123));
151
152 fn f() {
153 }
154 )";
155
156 auto* expect = R"(
157 var<private> a : vec3<i32> = vec3<i32>(123);
158
159 var<private> b : vec3<u32> = vec3<u32>(123u);
160
161 var<private> c : vec3<f32> = vec3<f32>(123.0);
162
163 var<private> d : vec3<bool> = vec3<bool>(true);
164
165 fn f() {
166 }
167 )";
168
169 auto got = Run<FoldConstants>(src);
170
171 EXPECT_EQ(expect, str(got));
172 }
173
TEST_F(FoldConstantsTest,Module_Vector_MultipleConversions)174 TEST_F(FoldConstantsTest, Module_Vector_MultipleConversions) {
175 auto* src = R"(
176 var<private> a : vec3<i32> = vec3<i32>(vec3<u32>(vec3<f32>(vec3<u32>(u32(123.0)))));
177 var<private> b : vec3<u32> = vec3<u32>(vec3<i32>(vec3<f32>(vec3<i32>(i32(123)))));
178 var<private> c : vec3<f32> = vec3<f32>(vec3<u32>(vec3<i32>(vec3<u32>(u32(123u)))));
179 var<private> d : vec3<bool> = vec3<bool>(vec3<i32>(vec3<f32>(vec3<i32>(i32(123)))));
180
181 fn f() {
182 }
183 )";
184
185 auto* expect = R"(
186 var<private> a : vec3<i32> = vec3<i32>(123);
187
188 var<private> b : vec3<u32> = vec3<u32>(123u);
189
190 var<private> c : vec3<f32> = vec3<f32>(123.0);
191
192 var<private> d : vec3<bool> = vec3<bool>(true);
193
194 fn f() {
195 }
196 )";
197
198 auto got = Run<FoldConstants>(src);
199
200 EXPECT_EQ(expect, str(got));
201 }
202
TEST_F(FoldConstantsTest,Module_Vector_MixedSizeConversions)203 TEST_F(FoldConstantsTest, Module_Vector_MixedSizeConversions) {
204 auto* src = R"(
205 var<private> a : vec4<i32> = vec4<i32>(vec3<i32>(vec3<u32>(1u, 2u, 3u)), 4);
206 var<private> b : vec4<i32> = vec4<i32>(vec2<i32>(vec2<u32>(1u, 2u)), vec2<i32>(4, 5));
207 var<private> c : vec4<i32> = vec4<i32>(1, vec2<i32>(vec2<f32>(2.0, 3.0)), 4);
208 var<private> d : vec4<i32> = vec4<i32>(1, 2, vec2<i32>(vec2<f32>(3.0, 4.0)));
209 var<private> e : vec4<bool> = vec4<bool>(false, bool(f32(1.0)), vec2<bool>(vec2<i32>(0, i32(4u))));
210
211 fn f() {
212 }
213 )";
214
215 auto* expect = R"(
216 var<private> a : vec4<i32> = vec4<i32>(1, 2, 3, 4);
217
218 var<private> b : vec4<i32> = vec4<i32>(1, 2, 4, 5);
219
220 var<private> c : vec4<i32> = vec4<i32>(1, 2, 3, 4);
221
222 var<private> d : vec4<i32> = vec4<i32>(1, 2, 3, 4);
223
224 var<private> e : vec4<bool> = vec4<bool>(false, true, false, true);
225
226 fn f() {
227 }
228 )";
229
230 auto got = Run<FoldConstants>(src);
231
232 EXPECT_EQ(expect, str(got));
233 }
234
TEST_F(FoldConstantsTest,Function_Scalar_NoConversion)235 TEST_F(FoldConstantsTest, Function_Scalar_NoConversion) {
236 auto* src = R"(
237 fn f() {
238 var a : i32 = i32(123);
239 var b : u32 = u32(123u);
240 var c : f32 = f32(123.0);
241 var d : bool = bool(true);
242 }
243 )";
244
245 auto* expect = R"(
246 fn f() {
247 var a : i32 = 123;
248 var b : u32 = 123u;
249 var c : f32 = 123.0;
250 var d : bool = true;
251 }
252 )";
253
254 auto got = Run<FoldConstants>(src);
255
256 EXPECT_EQ(expect, str(got));
257 }
258
TEST_F(FoldConstantsTest,Function_Scalar_Conversion)259 TEST_F(FoldConstantsTest, Function_Scalar_Conversion) {
260 auto* src = R"(
261 fn f() {
262 var a : i32 = i32(123.0);
263 var b : u32 = u32(123);
264 var c : f32 = f32(123u);
265 var d : bool = bool(123);
266 }
267 )";
268
269 auto* expect = R"(
270 fn f() {
271 var a : i32 = 123;
272 var b : u32 = 123u;
273 var c : f32 = 123.0;
274 var d : bool = true;
275 }
276 )";
277
278 auto got = Run<FoldConstants>(src);
279
280 EXPECT_EQ(expect, str(got));
281 }
282
TEST_F(FoldConstantsTest,Function_Scalar_MultipleConversions)283 TEST_F(FoldConstantsTest, Function_Scalar_MultipleConversions) {
284 auto* src = R"(
285 fn f() {
286 var a : i32 = i32(u32(f32(u32(i32(123.0)))));
287 var b : u32 = u32(i32(f32(i32(u32(123)))));
288 var c : f32 = f32(u32(i32(u32(f32(123u)))));
289 var d : bool = bool(i32(f32(i32(u32(123)))));
290 }
291 )";
292
293 auto* expect = R"(
294 fn f() {
295 var a : i32 = 123;
296 var b : u32 = 123u;
297 var c : f32 = 123.0;
298 var d : bool = true;
299 }
300 )";
301
302 auto got = Run<FoldConstants>(src);
303
304 EXPECT_EQ(expect, str(got));
305 }
306
TEST_F(FoldConstantsTest,Function_Vector_NoConversion)307 TEST_F(FoldConstantsTest, Function_Vector_NoConversion) {
308 auto* src = R"(
309 fn f() {
310 var a : vec3<i32> = vec3<i32>(123);
311 var b : vec3<u32> = vec3<u32>(123u);
312 var c : vec3<f32> = vec3<f32>(123.0);
313 var d : vec3<bool> = vec3<bool>(true);
314 }
315 )";
316
317 auto* expect = R"(
318 fn f() {
319 var a : vec3<i32> = vec3<i32>(123);
320 var b : vec3<u32> = vec3<u32>(123u);
321 var c : vec3<f32> = vec3<f32>(123.0);
322 var d : vec3<bool> = vec3<bool>(true);
323 }
324 )";
325
326 auto got = Run<FoldConstants>(src);
327
328 EXPECT_EQ(expect, str(got));
329 }
330
TEST_F(FoldConstantsTest,Function_Vector_Conversion)331 TEST_F(FoldConstantsTest, Function_Vector_Conversion) {
332 auto* src = R"(
333 fn f() {
334 var a : vec3<i32> = vec3<i32>(vec3<f32>(123.0));
335 var b : vec3<u32> = vec3<u32>(vec3<i32>(123));
336 var c : vec3<f32> = vec3<f32>(vec3<u32>(123u));
337 var d : vec3<bool> = vec3<bool>(vec3<i32>(123));
338 }
339 )";
340
341 auto* expect = R"(
342 fn f() {
343 var a : vec3<i32> = vec3<i32>(123);
344 var b : vec3<u32> = vec3<u32>(123u);
345 var c : vec3<f32> = vec3<f32>(123.0);
346 var d : vec3<bool> = vec3<bool>(true);
347 }
348 )";
349
350 auto got = Run<FoldConstants>(src);
351
352 EXPECT_EQ(expect, str(got));
353 }
354
TEST_F(FoldConstantsTest,Function_Vector_MultipleConversions)355 TEST_F(FoldConstantsTest, Function_Vector_MultipleConversions) {
356 auto* src = R"(
357 fn f() {
358 var a : vec3<i32> = vec3<i32>(vec3<u32>(vec3<f32>(vec3<u32>(u32(123.0)))));
359 var b : vec3<u32> = vec3<u32>(vec3<i32>(vec3<f32>(vec3<i32>(i32(123)))));
360 var c : vec3<f32> = vec3<f32>(vec3<u32>(vec3<i32>(vec3<u32>(u32(123u)))));
361 var d : vec3<bool> = vec3<bool>(vec3<i32>(vec3<f32>(vec3<i32>(i32(123)))));
362 }
363 )";
364
365 auto* expect = R"(
366 fn f() {
367 var a : vec3<i32> = vec3<i32>(123);
368 var b : vec3<u32> = vec3<u32>(123u);
369 var c : vec3<f32> = vec3<f32>(123.0);
370 var d : vec3<bool> = vec3<bool>(true);
371 }
372 )";
373
374 auto got = Run<FoldConstants>(src);
375
376 EXPECT_EQ(expect, str(got));
377 }
378
TEST_F(FoldConstantsTest,Function_Vector_MixedSizeConversions)379 TEST_F(FoldConstantsTest, Function_Vector_MixedSizeConversions) {
380 auto* src = R"(
381 fn f() {
382 var a : vec4<i32> = vec4<i32>(vec3<i32>(vec3<u32>(1u, 2u, 3u)), 4);
383 var b : vec4<i32> = vec4<i32>(vec2<i32>(vec2<u32>(1u, 2u)), vec2<i32>(4, 5));
384 var c : vec4<i32> = vec4<i32>(1, vec2<i32>(vec2<f32>(2.0, 3.0)), 4);
385 var d : vec4<i32> = vec4<i32>(1, 2, vec2<i32>(vec2<f32>(3.0, 4.0)));
386 var e : vec4<bool> = vec4<bool>(false, bool(f32(1.0)), vec2<bool>(vec2<i32>(0, i32(4u))));
387 }
388 )";
389
390 auto* expect = R"(
391 fn f() {
392 var a : vec4<i32> = vec4<i32>(1, 2, 3, 4);
393 var b : vec4<i32> = vec4<i32>(1, 2, 4, 5);
394 var c : vec4<i32> = vec4<i32>(1, 2, 3, 4);
395 var d : vec4<i32> = vec4<i32>(1, 2, 3, 4);
396 var e : vec4<bool> = vec4<bool>(false, true, false, true);
397 }
398 )";
399
400 auto got = Run<FoldConstants>(src);
401
402 EXPECT_EQ(expect, str(got));
403 }
404
TEST_F(FoldConstantsTest,Function_Vector_ConstantWithNonConstant)405 TEST_F(FoldConstantsTest, Function_Vector_ConstantWithNonConstant) {
406 auto* src = R"(
407 fn f() {
408 var a : f32 = f32();
409 var b : vec2<f32> = vec2<f32>(f32(i32(1)), a);
410 }
411 )";
412
413 auto* expect = R"(
414 fn f() {
415 var a : f32 = f32();
416 var b : vec2<f32> = vec2<f32>(1.0, a);
417 }
418 )";
419
420 auto got = Run<FoldConstants>(src);
421
422 EXPECT_EQ(expect, str(got));
423 }
424
425 } // namespace
426 } // namespace transform
427 } // namespace tint
428