• 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/pad_array_elements.h"
16 
17 #include <utility>
18 
19 #include "src/transform/test_helper.h"
20 
21 namespace tint {
22 namespace transform {
23 namespace {
24 
25 using PadArrayElementsTest = TransformTest;
26 
TEST_F(PadArrayElementsTest,EmptyModule)27 TEST_F(PadArrayElementsTest, EmptyModule) {
28   auto* src = "";
29   auto* expect = "";
30 
31   auto got = Run<PadArrayElements>(src);
32 
33   EXPECT_EQ(expect, str(got));
34 }
35 
TEST_F(PadArrayElementsTest,ImplicitArrayStride)36 TEST_F(PadArrayElementsTest, ImplicitArrayStride) {
37   auto* src = R"(
38 var<private> arr : array<i32, 4>;
39 )";
40   auto* expect = src;
41 
42   auto got = Run<PadArrayElements>(src);
43 
44   EXPECT_EQ(expect, str(got));
45 }
46 
TEST_F(PadArrayElementsTest,ArrayAsGlobal)47 TEST_F(PadArrayElementsTest, ArrayAsGlobal) {
48   auto* src = R"(
49 var<private> arr : [[stride(8)]] array<i32, 4>;
50 )";
51   auto* expect = R"(
52 struct tint_padded_array_element {
53   [[size(8)]]
54   el : i32;
55 };
56 
57 var<private> arr : array<tint_padded_array_element, 4u>;
58 )";
59 
60   auto got = Run<PadArrayElements>(src);
61 
62   EXPECT_EQ(expect, str(got));
63 }
64 
TEST_F(PadArrayElementsTest,RuntimeArray)65 TEST_F(PadArrayElementsTest, RuntimeArray) {
66   auto* src = R"(
67 [[block]]
68 struct S {
69   rta : [[stride(8)]] array<i32>;
70 };
71 )";
72   auto* expect = R"(
73 struct tint_padded_array_element {
74   [[size(8)]]
75   el : i32;
76 };
77 
78 [[block]]
79 struct S {
80   rta : array<tint_padded_array_element>;
81 };
82 )";
83 
84   auto got = Run<PadArrayElements>(src);
85 
86   EXPECT_EQ(expect, str(got));
87 }
88 
TEST_F(PadArrayElementsTest,ArrayFunctionVar)89 TEST_F(PadArrayElementsTest, ArrayFunctionVar) {
90   auto* src = R"(
91 fn f() {
92   var arr : [[stride(16)]] array<i32, 4>;
93   arr = [[stride(16)]] array<i32, 4>();
94   arr = [[stride(16)]] array<i32, 4>(1, 2, 3, 4);
95   let x = arr[3];
96 }
97 )";
98   auto* expect = R"(
99 struct tint_padded_array_element {
100   [[size(16)]]
101   el : i32;
102 };
103 
104 fn f() {
105   var arr : array<tint_padded_array_element, 4u>;
106   arr = array<tint_padded_array_element, 4u>();
107   arr = array<tint_padded_array_element, 4u>(tint_padded_array_element(1), tint_padded_array_element(2), tint_padded_array_element(3), tint_padded_array_element(4));
108   let x = arr[3].el;
109 }
110 )";
111 
112   auto got = Run<PadArrayElements>(src);
113 
114   EXPECT_EQ(expect, str(got));
115 }
116 
TEST_F(PadArrayElementsTest,ArrayAsParam)117 TEST_F(PadArrayElementsTest, ArrayAsParam) {
118   auto* src = R"(
119 fn f(a : [[stride(12)]] array<i32, 4>) -> i32 {
120   return a[2];
121 }
122 )";
123   auto* expect = R"(
124 struct tint_padded_array_element {
125   [[size(12)]]
126   el : i32;
127 };
128 
129 fn f(a : array<tint_padded_array_element, 4u>) -> i32 {
130   return a[2].el;
131 }
132 )";
133 
134   auto got = Run<PadArrayElements>(src);
135 
136   EXPECT_EQ(expect, str(got));
137 }
138 
139 // TODO(crbug.com/tint/781): Cannot parse the stride on the return array type.
TEST_F(PadArrayElementsTest,DISABLED_ArrayAsReturn)140 TEST_F(PadArrayElementsTest, DISABLED_ArrayAsReturn) {
141   auto* src = R"(
142 fn f() -> [[stride(8)]] array<i32, 4> {
143   return array<i32, 4>(1, 2, 3, 4);
144 }
145 )";
146   auto* expect = R"(
147 struct tint_padded_array_element {
148   el : i32;
149   [[size(4)]]
150   padding : u32;
151 };
152 
153 fn f() -> array<tint_padded_array_element, 4> {
154   return array<tint_padded_array_element, 4>(tint_padded_array_element(1, 0u), tint_padded_array_element(2, 0u), tint_padded_array_element(3, 0u), tint_padded_array_element(4, 0u));
155 }
156 )";
157 
158   auto got = Run<PadArrayElements>(src);
159 
160   EXPECT_EQ(expect, str(got));
161 }
162 
TEST_F(PadArrayElementsTest,ArrayAlias)163 TEST_F(PadArrayElementsTest, ArrayAlias) {
164   auto* src = R"(
165 type Array = [[stride(16)]] array<i32, 4>;
166 
167 fn f() {
168   var arr : Array;
169   arr = Array();
170   arr = Array(1, 2, 3, 4);
171   let vals : Array = Array(1, 2, 3, 4);
172   arr = vals;
173   let x = arr[3];
174 }
175 )";
176   auto* expect = R"(
177 struct tint_padded_array_element {
178   [[size(16)]]
179   el : i32;
180 };
181 
182 type Array = array<tint_padded_array_element, 4u>;
183 
184 fn f() {
185   var arr : array<tint_padded_array_element, 4u>;
186   arr = array<tint_padded_array_element, 4u>();
187   arr = array<tint_padded_array_element, 4u>(tint_padded_array_element(1), tint_padded_array_element(2), tint_padded_array_element(3), tint_padded_array_element(4));
188   let vals : array<tint_padded_array_element, 4u> = array<tint_padded_array_element, 4u>(tint_padded_array_element(1), tint_padded_array_element(2), tint_padded_array_element(3), tint_padded_array_element(4));
189   arr = vals;
190   let x = arr[3].el;
191 }
192 )";
193 
194   auto got = Run<PadArrayElements>(src);
195 
196   EXPECT_EQ(expect, str(got));
197 }
198 
TEST_F(PadArrayElementsTest,ArraysInStruct)199 TEST_F(PadArrayElementsTest, ArraysInStruct) {
200   auto* src = R"(
201 struct S {
202   a : [[stride(8)]] array<i32, 4>;
203   b : [[stride(8)]] array<i32, 8>;
204   c : [[stride(8)]] array<i32, 4>;
205   d : [[stride(12)]] array<i32, 8>;
206 };
207 )";
208   auto* expect = R"(
209 struct tint_padded_array_element {
210   [[size(8)]]
211   el : i32;
212 };
213 
214 struct tint_padded_array_element_1 {
215   [[size(8)]]
216   el : i32;
217 };
218 
219 struct tint_padded_array_element_2 {
220   [[size(12)]]
221   el : i32;
222 };
223 
224 struct S {
225   a : array<tint_padded_array_element, 4u>;
226   b : array<tint_padded_array_element_1, 8u>;
227   c : array<tint_padded_array_element, 4u>;
228   d : array<tint_padded_array_element_2, 8u>;
229 };
230 )";
231 
232   auto got = Run<PadArrayElements>(src);
233 
234   EXPECT_EQ(expect, str(got));
235 }
236 
TEST_F(PadArrayElementsTest,ArraysOfArraysInStruct)237 TEST_F(PadArrayElementsTest, ArraysOfArraysInStruct) {
238   auto* src = R"(
239 struct S {
240   a : [[stride(512)]] array<i32, 4>;
241   b : [[stride(512)]] array<[[stride(32)]] array<i32, 4>, 4>;
242   c : [[stride(512)]] array<[[stride(64)]] array<[[stride(8)]] array<i32, 4>, 4>, 4>;
243 };
244 )";
245   auto* expect = R"(
246 struct tint_padded_array_element {
247   [[size(512)]]
248   el : i32;
249 };
250 
251 struct tint_padded_array_element_2 {
252   [[size(32)]]
253   el : i32;
254 };
255 
256 struct tint_padded_array_element_1 {
257   [[size(512)]]
258   el : array<tint_padded_array_element_2, 4u>;
259 };
260 
261 struct tint_padded_array_element_5 {
262   [[size(8)]]
263   el : i32;
264 };
265 
266 struct tint_padded_array_element_4 {
267   [[size(64)]]
268   el : array<tint_padded_array_element_5, 4u>;
269 };
270 
271 struct tint_padded_array_element_3 {
272   [[size(512)]]
273   el : array<tint_padded_array_element_4, 4u>;
274 };
275 
276 struct S {
277   a : array<tint_padded_array_element, 4u>;
278   b : array<tint_padded_array_element_1, 4u>;
279   c : array<tint_padded_array_element_3, 4u>;
280 };
281 )";
282 
283   auto got = Run<PadArrayElements>(src);
284 
285   EXPECT_EQ(expect, str(got));
286 }
287 
TEST_F(PadArrayElementsTest,AccessArraysOfArraysInStruct)288 TEST_F(PadArrayElementsTest, AccessArraysOfArraysInStruct) {
289   auto* src = R"(
290 struct S {
291   a : [[stride(512)]] array<i32, 4>;
292   b : [[stride(512)]] array<[[stride(32)]] array<i32, 4>, 4>;
293   c : [[stride(512)]] array<[[stride(64)]] array<[[stride(8)]] array<i32, 4>, 4>, 4>;
294 };
295 
296 fn f(s : S) -> i32 {
297   return s.a[2] + s.b[1][2] + s.c[3][1][2];
298 }
299 )";
300   auto* expect = R"(
301 struct tint_padded_array_element {
302   [[size(512)]]
303   el : i32;
304 };
305 
306 struct tint_padded_array_element_2 {
307   [[size(32)]]
308   el : i32;
309 };
310 
311 struct tint_padded_array_element_1 {
312   [[size(512)]]
313   el : array<tint_padded_array_element_2, 4u>;
314 };
315 
316 struct tint_padded_array_element_5 {
317   [[size(8)]]
318   el : i32;
319 };
320 
321 struct tint_padded_array_element_4 {
322   [[size(64)]]
323   el : array<tint_padded_array_element_5, 4u>;
324 };
325 
326 struct tint_padded_array_element_3 {
327   [[size(512)]]
328   el : array<tint_padded_array_element_4, 4u>;
329 };
330 
331 struct S {
332   a : array<tint_padded_array_element, 4u>;
333   b : array<tint_padded_array_element_1, 4u>;
334   c : array<tint_padded_array_element_3, 4u>;
335 };
336 
337 fn f(s : S) -> i32 {
338   return ((s.a[2].el + s.b[1].el[2].el) + s.c[3].el[1].el[2].el);
339 }
340 )";
341 
342   auto got = Run<PadArrayElements>(src);
343 
344   EXPECT_EQ(expect, str(got));
345 }
346 
TEST_F(PadArrayElementsTest,DeclarationOrder)347 TEST_F(PadArrayElementsTest, DeclarationOrder) {
348   auto* src = R"(
349 type T0 = i32;
350 
351 type T1 = [[stride(8)]] array<i32, 1>;
352 
353 type T2 = i32;
354 
355 fn f1(a : [[stride(8)]] array<i32, 2>) {
356 }
357 
358 type T3 = i32;
359 
360 fn f2() {
361   var v : [[stride(8)]] array<i32, 3>;
362 }
363 )";
364   auto* expect = R"(
365 type T0 = i32;
366 
367 struct tint_padded_array_element {
368   [[size(8)]]
369   el : i32;
370 };
371 
372 type T1 = array<tint_padded_array_element, 1u>;
373 
374 type T2 = i32;
375 
376 struct tint_padded_array_element_1 {
377   [[size(8)]]
378   el : i32;
379 };
380 
381 fn f1(a : array<tint_padded_array_element_1, 2u>) {
382 }
383 
384 type T3 = i32;
385 
386 struct tint_padded_array_element_2 {
387   [[size(8)]]
388   el : i32;
389 };
390 
391 fn f2() {
392   var v : array<tint_padded_array_element_2, 3u>;
393 }
394 )";
395 
396   auto got = Run<PadArrayElements>(src);
397 
398   EXPECT_EQ(expect, str(got));
399 }
400 
401 }  // namespace
402 }  // namespace transform
403 }  // namespace tint
404