1 /*
2  * Copyright © 2017 Gert Wollny
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 
25 #include "st_tests_common.h"
26 
27 #include "tgsi/tgsi_ureg.h"
28 #include "tgsi/tgsi_info.h"
29 #include "mesa/program/prog_instruction.h"
30 #include "gtest/gtest.h"
31 
32 #include <utility>
33 #include <algorithm>
34 #include <iostream>
35 
36 using std::vector;
37 
38 using namespace tgsi_array_merge;
39 using ArrayLiveRangeMerge=testing::Test;
40 
TEST_F(ArrayLiveRangeMerge,SimpleLiveRange)41 TEST_F(ArrayLiveRangeMerge, SimpleLiveRange)
42 {
43    array_live_range a1(1, 10, 1, 5, WRITEMASK_X);
44    array_live_range a2(2, 5, 6, 10, WRITEMASK_X);
45 
46    array_live_range::merge(&a1, &a2);
47 
48    EXPECT_EQ(a1.array_id(), 1);
49    EXPECT_EQ(a1.begin(), 1);
50    EXPECT_EQ(a1.end(), 10);
51    EXPECT_EQ(a1.target_array_id(), 0);
52    EXPECT_EQ(a1.used_components(), 1);
53    EXPECT_EQ(a1.access_mask(), WRITEMASK_X);
54 
55    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
56    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
57    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
58    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
59 
60    EXPECT_EQ(a2.array_id(), 2);
61    EXPECT_EQ(a2.begin(), 6);
62    EXPECT_EQ(a2.end(), 10);
63    EXPECT_EQ(a2.target_array_id(), 1);
64    EXPECT_EQ(a2.used_components(), 1);
65    EXPECT_EQ(a2.access_mask(), WRITEMASK_X);
66 
67    EXPECT_EQ(a2.remap_one_swizzle(0), 0);
68    EXPECT_EQ(a2.remap_one_swizzle(1), 1);
69    EXPECT_EQ(a2.remap_one_swizzle(2), 2);
70    EXPECT_EQ(a2.remap_one_swizzle(3), 3);
71 }
72 
TEST_F(ArrayLiveRangeMerge,SimpleLiveRangeInverse)73 TEST_F(ArrayLiveRangeMerge, SimpleLiveRangeInverse)
74 {
75    array_live_range a1(1, 5, 1, 5, WRITEMASK_X);
76    array_live_range a2(2, 10, 6, 10, WRITEMASK_X);
77 
78    array_live_range::merge(&a1, &a2);
79 
80    EXPECT_EQ(a1.array_id(), 1);
81    EXPECT_EQ(a1.begin(), 1);
82    EXPECT_EQ(a1.end(), 5);
83    EXPECT_EQ(a1.target_array_id(), 2);
84    EXPECT_EQ(a1.used_components(), 1);
85    EXPECT_EQ(a1.access_mask(), WRITEMASK_X);
86 
87    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
88    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
89    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
90    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
91 
92    EXPECT_EQ(a2.array_id(), 2);
93    EXPECT_EQ(a2.begin(), 1);
94    EXPECT_EQ(a2.end(), 10);
95    EXPECT_EQ(a2.target_array_id(), 0);
96    EXPECT_EQ(a2.used_components(), 1);
97    EXPECT_EQ(a2.access_mask(), WRITEMASK_X);
98 
99    EXPECT_EQ(a2.remap_one_swizzle(0), 0);
100    EXPECT_EQ(a2.remap_one_swizzle(1), 1);
101    EXPECT_EQ(a2.remap_one_swizzle(2), 2);
102    EXPECT_EQ(a2.remap_one_swizzle(3), 3);
103 }
104 
105 
TEST_F(ArrayLiveRangeMerge,Interleave_x_xyz)106 TEST_F(ArrayLiveRangeMerge, Interleave_x_xyz)
107 {
108    array_live_range a1(1, 10, 1, 10, WRITEMASK_X);
109    array_live_range a2(2, 9, 1, 10, WRITEMASK_XYZ);
110 
111    array_live_range::interleave(&a1, &a2);
112 
113    EXPECT_EQ(a1.array_id(), 1);
114    EXPECT_EQ(a1.begin(), 1);
115    EXPECT_EQ(a1.end(), 10);
116    EXPECT_EQ(a1.array_length(), 10u);
117    EXPECT_EQ(a1.target_array_id(), 0);
118    EXPECT_EQ(a1.used_components(), 4);
119    EXPECT_EQ(a1.access_mask(), WRITEMASK_XYZW);
120 
121    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
122    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
123    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
124    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
125 
126    EXPECT_EQ(a2.array_id(), 2);
127    EXPECT_EQ(a2.begin(), 1);
128    EXPECT_EQ(a2.end(), 10);
129    EXPECT_EQ(a2.target_array_id(), 1);
130 
131    EXPECT_EQ(a2.remap_one_swizzle(0), 1);
132    EXPECT_EQ(a2.remap_one_swizzle(1), 2);
133    EXPECT_EQ(a2.remap_one_swizzle(2), 3);
134    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
135 }
136 
TEST_F(ArrayLiveRangeMerge,Interleave_xyz_x)137 TEST_F(ArrayLiveRangeMerge, Interleave_xyz_x)
138 {
139    array_live_range a1(1, 10, 1, 10, WRITEMASK_XYZ);
140    array_live_range a2(2, 9, 1, 10, WRITEMASK_X);
141 
142    array_live_range::interleave(&a1, &a2);
143 
144    EXPECT_EQ(a1.array_id(), 1);
145    EXPECT_EQ(a1.begin(), 1);
146    EXPECT_EQ(a1.end(), 10);
147    EXPECT_EQ(a1.array_length(), 10u);
148    EXPECT_EQ(a1.target_array_id(), 0);
149    EXPECT_EQ(a1.used_components(), 4);
150    EXPECT_EQ(a1.access_mask(), WRITEMASK_XYZW);
151 
152    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
153    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
154    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
155    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
156 
157    EXPECT_EQ(a2.array_id(), 2);
158    EXPECT_EQ(a2.begin(), 1);
159    EXPECT_EQ(a2.end(), 10);
160    EXPECT_EQ(a2.target_array_id(), 1);
161 
162    EXPECT_EQ(a2.remap_one_swizzle(0), 3);
163    EXPECT_EQ(a2.remap_one_swizzle(1), -1);
164    EXPECT_EQ(a2.remap_one_swizzle(2), -1);
165    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
166 }
167 
168 
TEST_F(ArrayLiveRangeMerge,SimpleInterleave)169 TEST_F(ArrayLiveRangeMerge, SimpleInterleave)
170 {
171    array_live_range a1(1, 10, 1, 10, WRITEMASK_X);
172    array_live_range a2(2, 9, 1, 10, WRITEMASK_X);
173 
174    array_live_range::interleave(&a1, &a2);
175 
176    EXPECT_EQ(a1.array_id(), 1);
177    EXPECT_EQ(a1.begin(), 1);
178    EXPECT_EQ(a1.end(), 10);
179    EXPECT_EQ(a1.array_length(), 10u);
180    EXPECT_EQ(a1.target_array_id(), 0);
181    EXPECT_EQ(a1.used_components(), 2);
182    EXPECT_EQ(a1.access_mask(), WRITEMASK_XY);
183 
184    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
185    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
186    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
187    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
188 
189    EXPECT_EQ(a2.array_id(), 2);
190    EXPECT_EQ(a2.begin(), 1);
191    EXPECT_EQ(a2.end(), 10);
192    EXPECT_EQ(a2.target_array_id(), 1);
193 
194    EXPECT_EQ(a2.remap_one_swizzle(0), 1);
195    EXPECT_EQ(a2.remap_one_swizzle(1), -1);
196    EXPECT_EQ(a2.remap_one_swizzle(2), -1);
197    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
198 }
199 
200 
TEST_F(ArrayLiveRangeMerge,SimpleInterleaveInverse)201 TEST_F(ArrayLiveRangeMerge, SimpleInterleaveInverse)
202 {
203    array_live_range a1(1, 8, 1, 10, WRITEMASK_X);
204    array_live_range a2(2, 9, 1, 10, WRITEMASK_X);
205 
206    array_live_range::interleave(&a1, &a2);
207 
208    EXPECT_EQ(a1.array_id(), 1);
209    EXPECT_EQ(a1.begin(), 1);
210    EXPECT_EQ(a1.end(), 10);
211    EXPECT_EQ(a1.target_array_id(), 2);
212 
213    EXPECT_EQ(a1.remap_one_swizzle(0), 1);
214    EXPECT_EQ(a1.remap_one_swizzle(1), -1);
215    EXPECT_EQ(a1.remap_one_swizzle(2), -1);
216    EXPECT_EQ(a1.remap_one_swizzle(3), -1);
217 
218    EXPECT_EQ(a2.array_id(), 2);
219    EXPECT_EQ(a2.target_array_id(), 0);
220    EXPECT_EQ(a2.begin(), 1);
221    EXPECT_EQ(a2.end(), 10);
222    EXPECT_EQ(a2.array_length(), 9u);
223    EXPECT_EQ(a2.used_components(), 2);
224    EXPECT_EQ(a2.access_mask(), WRITEMASK_XY);
225 }
226 
227 
TEST_F(ArrayLiveRangeMerge,InterleaveRiveRangeExtend)228 TEST_F(ArrayLiveRangeMerge, InterleaveRiveRangeExtend)
229 {
230    array_live_range a1(1, 10, 2, 9, WRITEMASK_X);
231    array_live_range a2(2, 9, 1, 10, WRITEMASK_X);
232 
233    array_live_range::interleave(&a1, &a2);
234 
235    EXPECT_EQ(a1.array_id(), 1);
236    EXPECT_EQ(a1.begin(), 1);
237    EXPECT_EQ(a1.end(), 10);
238    EXPECT_EQ(a1.array_length(), 10u);
239    EXPECT_EQ(a1.target_array_id(), 0);
240    EXPECT_EQ(a1.used_components(), 2);
241    EXPECT_EQ(a1.access_mask(), WRITEMASK_XY);
242 
243    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
244    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
245    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
246    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
247 
248    EXPECT_EQ(a2.array_id(), 2);
249    EXPECT_EQ(a2.begin(), 1);
250    EXPECT_EQ(a2.end(), 10);
251    EXPECT_EQ(a2.target_array_id(), 1);
252 
253    EXPECT_EQ(a2.remap_one_swizzle(0), 1);
254    EXPECT_EQ(a2.remap_one_swizzle(1), -1);
255    EXPECT_EQ(a2.remap_one_swizzle(2), -1);
256    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
257 }
258 
TEST_F(ArrayLiveRangeMerge,InterleaveLiveRangeExtendInverse)259 TEST_F(ArrayLiveRangeMerge, InterleaveLiveRangeExtendInverse)
260 {
261    array_live_range a1(1, 8, 2, 11, WRITEMASK_X);
262    array_live_range a2(2, 9, 1, 10, WRITEMASK_X);
263 
264    array_live_range::interleave(&a1, &a2);
265 
266    EXPECT_EQ(a1.array_id(), 1);
267    EXPECT_EQ(a1.begin(), 2);
268    EXPECT_EQ(a1.end(), 11);
269    EXPECT_EQ(a1.target_array_id(), 2);
270    EXPECT_EQ(a1.used_components(), 1);
271    EXPECT_EQ(a1.access_mask(), WRITEMASK_X);
272 
273    EXPECT_EQ(a1.remap_one_swizzle(0), 1);
274    EXPECT_EQ(a1.remap_one_swizzle(1), -1);
275    EXPECT_EQ(a1.remap_one_swizzle(2), -1);
276    EXPECT_EQ(a1.remap_one_swizzle(3), -1);
277 
278    EXPECT_EQ(a2.array_id(), 2);
279    EXPECT_EQ(a2.begin(), 1);
280    EXPECT_EQ(a2.end(), 11);
281    EXPECT_EQ(a2.target_array_id(), 0);
282    EXPECT_EQ(a2.used_components(), 2);
283    EXPECT_EQ(a2.access_mask(), WRITEMASK_XY);
284 
285    EXPECT_EQ(a2.remap_one_swizzle(0), 0);
286    EXPECT_EQ(a2.remap_one_swizzle(1), 1);
287    EXPECT_EQ(a2.remap_one_swizzle(2), 2);
288    EXPECT_EQ(a2.remap_one_swizzle(3), 3);
289 }
290 
TEST_F(ArrayLiveRangeMerge,InterleaveChained)291 TEST_F(ArrayLiveRangeMerge, InterleaveChained)
292 {
293    array_live_range a1(1, 8, 2, 11, WRITEMASK_X);
294    array_live_range a2(2, 9, 1, 10, WRITEMASK_X);
295    array_live_range a3(3, 10, 1, 10, WRITEMASK_X);
296 
297    array_live_range::interleave(&a1, &a2);
298    array_live_range::interleave(&a2, &a3);
299 
300    EXPECT_EQ(a1.array_id(), 1);
301    EXPECT_EQ(a1.begin(), 2);
302    EXPECT_EQ(a1.end(), 11);
303    EXPECT_EQ(a1.target_array_id(), 2);
304    EXPECT_EQ(a1.used_components(), 1);
305    EXPECT_EQ(a1.access_mask(), WRITEMASK_X);
306 
307    EXPECT_EQ(a1.remap_one_swizzle(0), 2);
308    EXPECT_EQ(a1.remap_one_swizzle(1), -1);
309    EXPECT_EQ(a1.remap_one_swizzle(2), -1);
310    EXPECT_EQ(a1.remap_one_swizzle(3), -1);
311 
312    EXPECT_EQ(a2.array_id(), 2);
313    EXPECT_EQ(a2.begin(), 1);
314    EXPECT_EQ(a2.end(), 11);
315    EXPECT_EQ(a2.target_array_id(), 3);
316    EXPECT_EQ(a2.used_components(), 2);
317    EXPECT_EQ(a2.access_mask(), WRITEMASK_XY);
318 
319    EXPECT_EQ(a2.remap_one_swizzle(0), 1);
320    EXPECT_EQ(a2.remap_one_swizzle(1), 2);
321    EXPECT_EQ(a2.remap_one_swizzle(2), -1);
322    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
323 
324    EXPECT_EQ(a3.array_id(), 3);
325    EXPECT_EQ(a3.begin(), 1);
326    EXPECT_EQ(a3.end(), 11);
327    EXPECT_EQ(a3.target_array_id(), 0);
328    EXPECT_EQ(a3.used_components(), 3);
329    EXPECT_EQ(a3.access_mask(), WRITEMASK_XYZ);
330 
331    EXPECT_EQ(a3.remap_one_swizzle(0), 0);
332    EXPECT_EQ(a3.remap_one_swizzle(1), 1);
333    EXPECT_EQ(a3.remap_one_swizzle(2), 2);
334    EXPECT_EQ(a3.remap_one_swizzle(3), 3);
335 }
336 
TEST_F(ArrayLiveRangeMerge,MergeInterleaveChained)337 TEST_F(ArrayLiveRangeMerge, MergeInterleaveChained)
338 {
339    array_live_range a1(1, 8, 1, 5, WRITEMASK_X);
340    array_live_range a2(2, 9, 6, 10, WRITEMASK_X);
341    array_live_range a3(3, 10, 1, 10, WRITEMASK_X);
342 
343    array_live_range::merge(&a1, &a2);
344    array_live_range::interleave(&a2, &a3);
345 
346    EXPECT_EQ(a1.array_id(), 1);
347    EXPECT_EQ(a1.begin(), 1);
348    EXPECT_EQ(a1.end(), 5);
349    EXPECT_EQ(a1.target_array_id(), 2);
350    EXPECT_EQ(a1.used_components(), 1);
351    EXPECT_EQ(a1.access_mask(), WRITEMASK_X);
352 
353    EXPECT_EQ(a1.remap_one_swizzle(0), 1);
354    EXPECT_EQ(a1.remap_one_swizzle(1), -1);
355    EXPECT_EQ(a1.remap_one_swizzle(2), -1);
356    EXPECT_EQ(a1.remap_one_swizzle(3), -1);
357 
358    EXPECT_EQ(a2.array_id(), 2);
359    EXPECT_EQ(a2.begin(), 1);
360    EXPECT_EQ(a2.end(), 10);
361    EXPECT_EQ(a2.target_array_id(), 3);
362    EXPECT_EQ(a2.used_components(), 1);
363    EXPECT_EQ(a2.access_mask(), WRITEMASK_X);
364 
365    EXPECT_EQ(a2.remap_one_swizzle(0), 1);
366    EXPECT_EQ(a2.remap_one_swizzle(1), -1);
367    EXPECT_EQ(a2.remap_one_swizzle(2), -1);
368    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
369 
370    EXPECT_EQ(a3.array_id(), 3);
371    EXPECT_EQ(a3.begin(), 1);
372    EXPECT_EQ(a3.end(), 10);
373    EXPECT_EQ(a3.target_array_id(), 0);
374    EXPECT_EQ(a3.used_components(), 2);
375    EXPECT_EQ(a3.access_mask(), WRITEMASK_XY);
376 
377    EXPECT_EQ(a3.remap_one_swizzle(0), 0);
378    EXPECT_EQ(a3.remap_one_swizzle(1), 1);
379    EXPECT_EQ(a3.remap_one_swizzle(2), 2);
380    EXPECT_EQ(a3.remap_one_swizzle(3), 3);
381 }
382 
TEST_F(ArrayLiveRangeMerge,MergeMergeAndInterleave)383 TEST_F(ArrayLiveRangeMerge, MergeMergeAndInterleave)
384 {
385    array_live_range a1(1, 5, 1, 5, WRITEMASK_X);
386    array_live_range a2(2, 4, 6, 7, WRITEMASK_X);
387    array_live_range a3(3, 3, 1, 5, WRITEMASK_X);
388    array_live_range a4(4, 2, 6, 8, WRITEMASK_X);
389 
390    array_live_range::merge(&a1, &a2);
391    array_live_range::merge(&a3, &a4);
392    array_live_range::interleave(&a1, &a3);
393 
394    EXPECT_EQ(a1.array_id(), 1);
395    EXPECT_EQ(a1.begin(), 1);
396    EXPECT_EQ(a1.end(), 8);
397    EXPECT_EQ(a1.target_array_id(), 0);
398    EXPECT_EQ(a1.used_components(), 2);
399    EXPECT_EQ(a1.access_mask(), WRITEMASK_XY);
400 
401    EXPECT_EQ(a1.remap_one_swizzle(0), 0);
402    EXPECT_EQ(a1.remap_one_swizzle(1), 1);
403    EXPECT_EQ(a1.remap_one_swizzle(2), 2);
404    EXPECT_EQ(a1.remap_one_swizzle(3), 3);
405 
406    EXPECT_EQ(a2.array_id(), 2);
407    EXPECT_EQ(a2.begin(), 6);
408    EXPECT_EQ(a2.end(), 7);
409    EXPECT_EQ(a2.target_array_id(), 1);
410    EXPECT_EQ(a2.used_components(), 1);
411    EXPECT_EQ(a2.access_mask(), WRITEMASK_X);
412 
413    EXPECT_EQ(a2.remap_one_swizzle(0), 0);
414    EXPECT_EQ(a2.remap_one_swizzle(1), 1);
415    EXPECT_EQ(a2.remap_one_swizzle(2), 2);
416    EXPECT_EQ(a2.remap_one_swizzle(3), 3);
417 
418    EXPECT_EQ(a3.array_id(), 3);
419    EXPECT_EQ(a3.begin(), 1);
420    EXPECT_EQ(a3.end(), 8);
421    EXPECT_EQ(a3.target_array_id(), 1);
422    EXPECT_EQ(a3.used_components(), 1);
423    EXPECT_EQ(a3.access_mask(), WRITEMASK_X);
424 
425    EXPECT_EQ(a3.remap_one_swizzle(0), 1);
426    EXPECT_EQ(a3.remap_one_swizzle(1), -1);
427    EXPECT_EQ(a3.remap_one_swizzle(2), -1);
428    EXPECT_EQ(a3.remap_one_swizzle(3), -1);
429 
430    EXPECT_EQ(a4.array_id(), 4);
431    EXPECT_EQ(a4.begin(), 6);
432    EXPECT_EQ(a4.end(), 8);
433    EXPECT_EQ(a4.target_array_id(), 3);
434    EXPECT_EQ(a4.used_components(), 1);
435    EXPECT_EQ(a4.access_mask(), WRITEMASK_X);
436 
437    EXPECT_EQ(a4.remap_one_swizzle(0), 1);
438    EXPECT_EQ(a4.remap_one_swizzle(1), -1);
439    EXPECT_EQ(a4.remap_one_swizzle(2), -1);
440    EXPECT_EQ(a4.remap_one_swizzle(3), -1);
441 
442 }
443 
444 
TEST_F(ArrayLiveRangeMerge,MergeInterleaveMergeInterleaveChained)445 TEST_F(ArrayLiveRangeMerge, MergeInterleaveMergeInterleaveChained)
446 {
447    array_live_range a1(1, 8, 1, 5, WRITEMASK_X);
448    array_live_range a2(2, 9, 6, 10, WRITEMASK_X);
449    array_live_range a3(3, 10, 1, 10, WRITEMASK_X);
450    array_live_range a4(4, 11, 11, 20, WRITEMASK_XY);
451    array_live_range a5(5, 15, 5, 20, WRITEMASK_XY);
452 
453    array_live_range::merge(&a1, &a2);
454    array_live_range::interleave(&a2, &a3);    // a2 -> a3
455    array_live_range::merge(&a3, &a4);
456    array_live_range::interleave(&a4, &a5);    // a4 -> a5
457 
458 
459    EXPECT_EQ(a1.array_id(), 1);
460    EXPECT_EQ(a1.begin(), 1);
461    EXPECT_EQ(a1.end(), 5);
462    EXPECT_EQ(a1.target_array_id(), 2);
463    EXPECT_EQ(a1.used_components(), 1);
464    EXPECT_EQ(a1.access_mask(), WRITEMASK_X);
465 
466    EXPECT_EQ(a1.remap_one_swizzle(0), 3);
467    EXPECT_EQ(a1.remap_one_swizzle(1), -1);
468    EXPECT_EQ(a1.remap_one_swizzle(2), -1);
469    EXPECT_EQ(a1.remap_one_swizzle(3), -1);
470 
471    EXPECT_EQ(a2.array_id(), 2);
472    EXPECT_EQ(a2.begin(), 1);
473    EXPECT_EQ(a2.end(), 10);
474    EXPECT_EQ(a2.target_array_id(), 3);
475    EXPECT_EQ(a2.used_components(), 1);
476    EXPECT_EQ(a2.access_mask(), WRITEMASK_X);
477 
478    EXPECT_EQ(a2.remap_one_swizzle(0), 3);
479    EXPECT_EQ(a2.remap_one_swizzle(1), -1);
480    EXPECT_EQ(a2.remap_one_swizzle(2), -1);
481    EXPECT_EQ(a2.remap_one_swizzle(3), -1);
482 
483    EXPECT_EQ(a3.array_id(), 3);
484    EXPECT_EQ(a3.begin(), 1);
485    EXPECT_EQ(a3.end(), 10);
486    EXPECT_EQ(a3.target_array_id(), 4);
487    EXPECT_EQ(a3.used_components(), 2);
488    EXPECT_EQ(a3.access_mask(), WRITEMASK_XY);
489 
490    EXPECT_EQ(a3.remap_one_swizzle(0), 2);
491    EXPECT_EQ(a3.remap_one_swizzle(1), 3);
492    EXPECT_EQ(a3.remap_one_swizzle(2), -1);
493    EXPECT_EQ(a3.remap_one_swizzle(3), -1);
494 
495    EXPECT_EQ(a4.array_id(), 4);
496    EXPECT_EQ(a4.begin(), 1);
497    EXPECT_EQ(a4.end(), 20);
498    EXPECT_EQ(a4.target_array_id(), 5);
499    EXPECT_EQ(a4.used_components(), 2);
500    EXPECT_EQ(a4.access_mask(), WRITEMASK_XY);
501 
502    EXPECT_EQ(a4.remap_one_swizzle(0), 2);
503    EXPECT_EQ(a4.remap_one_swizzle(1), 3);
504    EXPECT_EQ(a4.remap_one_swizzle(2), -1);
505    EXPECT_EQ(a4.remap_one_swizzle(3), -1);
506 
507    EXPECT_EQ(a5.array_id(), 5);
508    EXPECT_EQ(a5.begin(), 1);
509    EXPECT_EQ(a5.end(), 20);
510    EXPECT_EQ(a5.target_array_id(), 0);
511    EXPECT_EQ(a5.used_components(), 4);
512    EXPECT_EQ(a5.access_mask(), WRITEMASK_XYZW);
513 
514    EXPECT_EQ(a5.remap_one_swizzle(0), 0);
515    EXPECT_EQ(a5.remap_one_swizzle(1), 1);
516    EXPECT_EQ(a5.remap_one_swizzle(2), 2);
517    EXPECT_EQ(a5.remap_one_swizzle(3), 3);
518 }
519 
520 using ArrayMergeTest=testing::Test;
521 
TEST_F(ArrayMergeTest,ArrayMergeTwoSwizzles)522 TEST_F(ArrayMergeTest, ArrayMergeTwoSwizzles)
523 {
524    vector<array_live_range> alt = {
525       {1, 4, 1, 5, WRITEMASK_X},
526       {2, 4, 2, 5, WRITEMASK_X},
527    };
528 
529    int8_t expect_swizzle[] = {1, -1, -1, -1};
530    vector<array_remapping> expect = {
531       {},
532       {1, expect_swizzle},
533    };
534 
535    vector<array_remapping> result(alt.size() + 1);
536 
537    get_array_remapping(2, &alt[0], &result[0]);
538 
539    EXPECT_EQ(result[1], expect[0]);
540    EXPECT_EQ(result[2], expect[1]);
541 
542 }
543 
TEST_F(ArrayMergeTest,ArrayMergeFourSwizzles)544 TEST_F(ArrayMergeTest, ArrayMergeFourSwizzles)
545 {
546    vector<array_live_range> alt = {
547       {1, 8, 1, 7, WRITEMASK_X},
548       {2, 7, 2, 7, WRITEMASK_X},
549       {3, 6, 3, 7, WRITEMASK_X},
550       {4, 5, 4, 7, WRITEMASK_X},
551    };
552    int8_t expect_swizzle1[] = {1, -1, -1, -1};
553    int8_t expect_swizzle2[] = {2, -1, -1, -1};
554    int8_t expect_swizzle3[] = {3, -1, -1, -1};
555 
556    vector<array_remapping> expect = {
557       {},
558       {1, expect_swizzle1},
559       {1, expect_swizzle2},
560       {1, expect_swizzle3},
561    };
562 
563    vector<array_remapping> result(alt.size() + 1);
564 
565    get_array_remapping(4, &alt[0], &result[0]);
566 
567    EXPECT_EQ(result[1], expect[0]);
568    EXPECT_EQ(result[2], expect[1]);
569    EXPECT_EQ(result[3], expect[2]);
570    EXPECT_EQ(result[4], expect[3]);
571 
572 }
573 
574 
TEST_F(ArrayMergeTest,SimpleChainMerge)575 TEST_F(ArrayMergeTest, SimpleChainMerge)
576 {
577    vector<array_live_range> input = {
578       {1, 3, 1, 5, WRITEMASK_XYZW},
579       {2, 2, 6, 7, WRITEMASK_XYZW},
580    };
581 
582    int8_t expect_swizzle[] = {0, 1, 2, 3};
583    vector<array_remapping> expect = {
584       {},
585       {1, expect_swizzle},
586    };
587 
588    vector<array_remapping> result(3);
589    get_array_remapping(2, &input[0], &result[0]);
590 
591    EXPECT_EQ(result[1], expect[0]);
592    EXPECT_EQ(result[2], expect[1]);
593 }
594 
TEST_F(ArrayMergeTest,MergeAndInterleave)595 TEST_F(ArrayMergeTest, MergeAndInterleave)
596 {
597    vector<array_live_range> input = {
598       {1, 5, 1, 5, WRITEMASK_X},
599       {2, 4, 6, 7, WRITEMASK_X},
600       {3, 3, 1, 5, WRITEMASK_X},
601       {4, 2, 6, 7, WRITEMASK_X},
602    };
603 
604    int8_t expect_swizzle1[] = {0,  1,  2,  3};
605    int8_t expect_swizzle2[] = {1, -1, -1, -1};
606    int8_t expect_swizzle3[] = {1, -1, -1, -1};
607 
608    vector<array_remapping> expect = {
609       {},
610       {1, expect_swizzle1},
611       {1, expect_swizzle2},
612       {1, expect_swizzle3}
613    };
614    vector<array_remapping> result(input.size() + 1);
615    get_array_remapping(input.size(), &input[0], &result[0]);
616 
617    EXPECT_EQ(result[1], expect[0]);
618    EXPECT_EQ(result[2], expect[1]);
619    EXPECT_EQ(result[3], expect[2]);
620    EXPECT_EQ(result[4], expect[3]);
621 }
622 
TEST_F(ArrayMergeTest,MergeAndInterleave2)623 TEST_F(ArrayMergeTest, MergeAndInterleave2)
624 {
625    vector<array_live_range> input = {
626       {1, 5, 1, 5, WRITEMASK_X},
627       {2, 4, 6, 7, WRITEMASK_X},
628       {3, 3, 1, 8, WRITEMASK_XY},
629       {4, 2, 6, 7, WRITEMASK_X},
630    };
631 
632    int8_t expect_swizzle1[] = {0,  1,  2,  3};
633    int8_t expect_swizzle2[] = {1,  2, -1, -1};
634    int8_t expect_swizzle3[] = {3, -1, -1, -1};
635 
636    vector<array_remapping> expect = {
637       {},
638       {1, expect_swizzle1},
639       {1, expect_swizzle2},
640       {1, expect_swizzle3}
641    };
642    vector<array_remapping> result(input.size() + 1);
643    get_array_remapping(input.size(), &input[0], &result[0]);
644 
645    EXPECT_EQ(result[1], expect[0]);
646    EXPECT_EQ(result[2], expect[1]);
647    EXPECT_EQ(result[3], expect[2]);
648    EXPECT_EQ(result[4], expect[3]);
649 }
650 
651 
TEST_F(ArrayMergeTest,MergeAndInterleave3)652 TEST_F(ArrayMergeTest, MergeAndInterleave3)
653 {
654    vector<array_live_range> input = {
655       {1, 5, 1, 5, WRITEMASK_X},
656       {2, 4, 6, 7, WRITEMASK_XY},
657       {3, 3, 1, 5, WRITEMASK_X}
658    };
659 
660    int8_t expect_swizzle1[] = {0, 1, 2, 3};
661    int8_t expect_swizzle2[] = {1, -1, -1, -1};
662 
663    vector<array_remapping> expect = {
664       {},
665       {1, expect_swizzle1},
666       {1, expect_swizzle2}
667    };
668    vector<array_remapping> result(input.size() + 1);
669    get_array_remapping(input.size(), &input[0], &result[0]);
670 
671    EXPECT_EQ(result[1], expect[0]);
672    EXPECT_EQ(result[2], expect[1]);
673    EXPECT_EQ(result[3], expect[2]);
674 }
675 
TEST_F(ArrayMergeTest,MergeAndInterleave4)676 TEST_F(ArrayMergeTest, MergeAndInterleave4)
677 {
678    vector<array_live_range> input = {
679       {1, 7, 1, 5, WRITEMASK_X},
680       {2, 6, 6, 7, WRITEMASK_XY},
681       {3, 5, 1, 5, WRITEMASK_X},
682       {4, 4, 8, 9, WRITEMASK_XYZ},
683       {5, 3, 8, 9, WRITEMASK_W},
684       {6, 2, 10, 11, WRITEMASK_XYZW},
685    };
686 
687    int8_t expect_swizzle1[] = {0, 1,  2,  3};
688    int8_t expect_swizzle2[] = {1, -1, -1, -1};
689    int8_t expect_swizzle3[] = {0, 1, 2, 3};
690    int8_t expect_swizzle4[] = {-1, -1, -1, 3};
691    int8_t expect_swizzle5[] = {0, 1, 2, 3};
692 
693    vector<array_remapping> expect = {
694       {},
695       {1, expect_swizzle1},
696       {1, expect_swizzle2},
697       {1, expect_swizzle3}, /* W from below will be interleaved in */
698       {1, expect_swizzle4},
699       {1, expect_swizzle5}
700    };
701    vector<array_remapping> result(input.size() + 1);
702    get_array_remapping(input.size(), &input[0], &result[0]);
703 
704    EXPECT_EQ(result[1], expect[0]);
705    EXPECT_EQ(result[2], expect[1]);
706    EXPECT_EQ(result[3], expect[2]);
707    EXPECT_EQ(result[4], expect[3]);
708    EXPECT_EQ(result[5], expect[4]);
709    EXPECT_EQ(result[6], expect[5]);
710 
711 }
712 
TEST_F(ArrayMergeTest,MergeAndInterleave5)713 TEST_F(ArrayMergeTest, MergeAndInterleave5)
714 {
715    vector<array_live_range> input = {
716       {1, 7, 1, 5, WRITEMASK_X},
717       {2, 6, 1, 3, WRITEMASK_X},
718       {3, 5, 4, 5, WRITEMASK_X},
719       {4, 4, 6, 10, WRITEMASK_XY},
720       {5, 8, 1, 10, WRITEMASK_XY}
721    };
722 
723    /* 1. merge 3 into 2
724     * 2. interleave 2 into 1 (x -> y) --- (y -> w)
725     * 3. merge 4 into 1                 /
726     * 4. interleave 1 into 5 (x,y - z,w)
727     */
728 
729    /* swizzle1 holds the summary mask */
730    int8_t expect_swizzle1[] = {2,  3, -1, -1};
731    int8_t expect_swizzle2[] = {3, -1, -1, -1};
732    int8_t expect_swizzle3[] = {3, -1, -1, -1};
733    int8_t expect_swizzle4[] = {2,  3, -1, -1};
734 
735    vector<array_remapping> expect = {
736       {5, expect_swizzle1},
737       {5, expect_swizzle2},
738       {5, expect_swizzle3},
739       {5, expect_swizzle4},
740       {}
741    };
742    vector<array_remapping> result(input.size() + 1);
743    get_array_remapping(input.size(), &input[0], &result[0]);
744 
745    EXPECT_EQ(result[1], expect[0]);
746    EXPECT_EQ(result[2], expect[1]);
747    EXPECT_EQ(result[3], expect[2]);
748    EXPECT_EQ(result[4], expect[3]);
749    EXPECT_EQ(result[5], expect[4]);
750 
751 }
752 
753 /* Test two arrays life time simple */
TEST_F(LifetimeEvaluatorExactTest,TwoArraysSimple)754 TEST_F(LifetimeEvaluatorExactTest, TwoArraysSimple)
755 {
756    const vector<FakeCodeline> code = {
757       { TGSI_OPCODE_MOV , {MT(1, 1, WRITEMASK_XYZW)}, {MT(0, in0, "")}, {}, ARR()},
758       { TGSI_OPCODE_MOV , {MT(2, 1, WRITEMASK_XYZW)}, {MT(0, in1, "")}, {}, ARR()},
759       { TGSI_OPCODE_ADD , {MT(0,out0, WRITEMASK_XYZW)}, {MT(1,1,"xyzw"), MT(2,1,"xyzw")}, {}, ARR()},
760       { TGSI_OPCODE_END}
761    };
762    run (code, array_lt_expect({{1,2,0,2, WRITEMASK_XYZW}, {2,2,1,2, WRITEMASK_XYZW}}));
763 }
764 
765 /* Test two arrays life time simple */
TEST_F(LifetimeEvaluatorExactTest,TwoArraysSimpleSwizzleX_Y)766 TEST_F(LifetimeEvaluatorExactTest, TwoArraysSimpleSwizzleX_Y)
767 {
768    const vector<FakeCodeline> code = {
769       { TGSI_OPCODE_MOV , {MT(1, 1, WRITEMASK_X)}, {MT(0, in0, "")}, {}, ARR()},
770       { TGSI_OPCODE_MOV , {MT(2, 1, WRITEMASK_Y)}, {MT(0, in1, "")}, {}, ARR()},
771       { TGSI_OPCODE_ADD , {MT(0,out0,1)}, {MT(1,1,"x"), MT(2,1,"y")}, {}, ARR()},
772       { TGSI_OPCODE_END}
773    };
774    run (code, array_lt_expect({{1, 2, 0, 2, WRITEMASK_X}, {2, 2, 1, 2, WRITEMASK_Y}}));
775 }
776 
777 /* Test array written before loop and read inside, must survive the loop */
TEST_F(LifetimeEvaluatorExactTest,ArraysWriteBeforLoopReadInside)778 TEST_F(LifetimeEvaluatorExactTest, ArraysWriteBeforLoopReadInside)
779 {
780    const vector<FakeCodeline> code = {
781       { TGSI_OPCODE_MOV, {1}, {in1}, {}},
782       { TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_X)}, {MT(0, in0, "")}, {}, ARR()},
783       { TGSI_OPCODE_BGNLOOP },
784       { TGSI_OPCODE_ADD, {MT(0,1, WRITEMASK_X)}, {MT(1,1,"x"), {MT(0,1, "x")}}, {}, ARR()},
785       { TGSI_OPCODE_ENDLOOP },
786       { TGSI_OPCODE_MOV, {out0}, {1}, {}},
787       { TGSI_OPCODE_END}
788    };
789    run (code, array_lt_expect({{1, 1, 1, 4, WRITEMASK_X}}));
790 }
791 
792 /* Test array written conditionally in loop must survive the whole loop */
TEST_F(LifetimeEvaluatorExactTest,ArraysConditionalWriteInNestedLoop)793 TEST_F(LifetimeEvaluatorExactTest, ArraysConditionalWriteInNestedLoop)
794 {
795    const vector<FakeCodeline> code = {
796       { TGSI_OPCODE_MOV, {1}, {in1}, {}},
797       { TGSI_OPCODE_BGNLOOP },
798       {   TGSI_OPCODE_BGNLOOP },
799       {     TGSI_OPCODE_IF, {}, {1}, {}},
800       {       TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_Z)}, {MT(0, in0, "")}, {}, ARR()},
801       {     TGSI_OPCODE_ENDIF },
802       {     TGSI_OPCODE_ADD, {MT(0,1, WRITEMASK_X)}, {MT(1,1,"z"), {MT(0,1, "x")}}, {}, ARR()},
803       {   TGSI_OPCODE_ENDLOOP },
804       { TGSI_OPCODE_ENDLOOP },
805       { TGSI_OPCODE_MOV, {out0}, {1}, {}},
806       { TGSI_OPCODE_END}
807    };
808    run (code, array_lt_expect({{1, 1, 1, 8, WRITEMASK_Z}}));
809 }
810 
811 /* Test array read conditionally in loop before write must
812  * survive the whole loop
813  */
TEST_F(LifetimeEvaluatorExactTest,ArraysConditionalReadBeforeWriteInNestedLoop)814 TEST_F(LifetimeEvaluatorExactTest, ArraysConditionalReadBeforeWriteInNestedLoop)
815 {
816    const vector<FakeCodeline> code = {
817       { TGSI_OPCODE_MOV, {1}, {in1}, {}},
818       { TGSI_OPCODE_BGNLOOP },
819       {   TGSI_OPCODE_BGNLOOP },
820       {     TGSI_OPCODE_IF, {}, {1}, {}},
821       {     TGSI_OPCODE_ADD, {MT(0,1, WRITEMASK_X)}, {MT(1,1,"z"), {MT(0,1, "x")}}, {}, ARR()},
822       {     TGSI_OPCODE_ENDIF },
823       {       TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_Z)}, {MT(0, in0, "")}, {}, ARR()},
824       {   TGSI_OPCODE_ENDLOOP },
825       { TGSI_OPCODE_ENDLOOP },
826       { TGSI_OPCODE_MOV, {out0}, {1}, {}},
827       { TGSI_OPCODE_END}
828    };
829    run (code, array_lt_expect({{1, 1, 1, 8, WRITEMASK_Z}}));
830 }
831 
832 
833 /* Test array written conditionally in loop must survive the whole loop */
TEST_F(LifetimeEvaluatorExactTest,ArraysConditionalWriteInNestedLoop2)834 TEST_F(LifetimeEvaluatorExactTest, ArraysConditionalWriteInNestedLoop2)
835 {
836    const vector<FakeCodeline> code = {
837       { TGSI_OPCODE_MOV, {1}, {in1}, {}},
838       { TGSI_OPCODE_BGNLOOP },
839       {   TGSI_OPCODE_BGNLOOP },
840       {     TGSI_OPCODE_IF, {}, {1}, {}},
841       {       TGSI_OPCODE_BGNLOOP },
842       {         TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_Z)}, {MT(0, in0, "")}, {}, ARR()},
843       {       TGSI_OPCODE_ENDLOOP },
844       {     TGSI_OPCODE_ENDIF },
845       {     TGSI_OPCODE_ADD, {MT(0,1, WRITEMASK_X)}, {MT(1,1,"z"), {MT(0,1, "x")}}, {}, ARR()},
846       {   TGSI_OPCODE_ENDLOOP },
847       { TGSI_OPCODE_ENDLOOP },
848       { TGSI_OPCODE_MOV, {out0}, {1}, {}},
849       { TGSI_OPCODE_END}
850    };
851    run (code, array_lt_expect({{1, 1, 1, 10, WRITEMASK_Z}}));
852 }
853 
854 
855 /* Test distinct loops */
TEST_F(LifetimeEvaluatorExactTest,ArraysReadWriteInSeparateScopes)856 TEST_F(LifetimeEvaluatorExactTest, ArraysReadWriteInSeparateScopes)
857 {
858    const vector<FakeCodeline> code = {
859       { TGSI_OPCODE_MOV, {1}, {in1}, {}},
860       { TGSI_OPCODE_BGNLOOP },
861       {   TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_W)}, {MT(0, in0, "")}, {}, ARR()},
862       { TGSI_OPCODE_ENDLOOP },
863       { TGSI_OPCODE_BGNLOOP },
864       {   TGSI_OPCODE_ADD, {MT(0,1, WRITEMASK_X)}, {MT(1,1,"w"), {MT(0,1, "x")}}, {}, ARR()},
865       { TGSI_OPCODE_ENDLOOP },
866       { TGSI_OPCODE_MOV, {out0}, {1}, {}},
867       { TGSI_OPCODE_END}
868    };
869    run (code, array_lt_expect({{1, 1, 2, 6, WRITEMASK_W}}));
870 }
871 
872 class ArrayRemapTest: public MesaTestWithMemCtx {
873 
874 public:
875    void run (const vector<FakeCodeline>& code,
876 	     const vector<FakeCodeline>& expect,
877 	     vector<unsigned> array_sizes,
878 	     vector<array_remapping>& remapping) const;
879 
880 
881 };
882 
TEST_F(ArrayRemapTest,ApplyMerge)883 TEST_F(ArrayRemapTest, ApplyMerge)
884 {
885    vector<unsigned> array_sizes{0, 12, 11, 10, 9, 8, 7};
886 
887    int8_t set_swizzle3[] = {1, -1, -1, -1};
888    int8_t set_swizzle5[] = {3, -1, -1, -1};
889    int8_t set_no_reswizzle[] = {0, 1, 2, 3};
890 
891    vector<array_remapping> remapping = {
892       {},
893       array_remapping(),
894       {1, set_no_reswizzle},
895       {1, set_swizzle3},
896       {1, set_no_reswizzle},
897       {1, set_swizzle5},
898       {1, set_no_reswizzle}
899    };
900 
901    const vector<FakeCodeline> code = {
902       { TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_X)}, {MT(0, in0, "x")}, {}, ARR()},
903       { TGSI_OPCODE_MOV, {MT(2, 2, WRITEMASK_XY)}, {MT(0, in0, "xy")}, {}, ARR()},
904       { TGSI_OPCODE_MOV, {MT(3, 3, WRITEMASK_X)}, {MT(0, in0, "x")}, {}, ARR()},
905       { TGSI_OPCODE_MOV, {MT(4, 4, WRITEMASK_XYZ)}, {MT(0, in0, "xyz")}, {}, ARR()},
906       { TGSI_OPCODE_MOV, {MT(5, 5, WRITEMASK_X)}, {MT(0, in0, "x")}, {}, ARR()},
907       { TGSI_OPCODE_MOV, {MT(6, 6, WRITEMASK_XYZW)}, {MT(0, in0, "xyzw")}, {}, ARR()},
908 
909       { TGSI_OPCODE_ADD, {MT(0, out0, WRITEMASK_X)}, {MT(1, 1, "x"), MT(0, in0, "y")}, {}, ARR()},
910       { TGSI_OPCODE_ADD, {MT(0, out0, WRITEMASK_YZ)}, {MT(2, 2, "xy"), MT(0, in0, "yz")}, {}, ARR()},
911       { TGSI_OPCODE_MUL, {MT(0, out0, WRITEMASK_W)}, {MT(3, 3, "x"), MT(0, in0, "x")}, {}, ARR()},
912       { TGSI_OPCODE_ADD, {MT(0, out1, WRITEMASK_XYZ)}, {MT(4, 4, "xyz"), MT(0, in0, "xyz")}, {}, ARR()},
913       { TGSI_OPCODE_MAD, {MT(0, out1, WRITEMASK_W)}, {MT(5, 5, "x"), MT(3, 1, "x"), MT(1, 1, "x")}, {}, ARR()},
914       { TGSI_OPCODE_ADD, {MT(0, out2, WRITEMASK_XYZW)}, {MT(6, 6, "xyzw"), MT(0, in0, "xyzw")}, {}, ARR()},
915 
916       { TGSI_OPCODE_END}
917    };
918 
919    const vector<FakeCodeline> expect = {
920       { TGSI_OPCODE_MOV, {MT(1, 1, WRITEMASK_X)}, {MT(0, in0, "x")}, {}, ARR()},
921       { TGSI_OPCODE_MOV, {MT(1, 2, WRITEMASK_XY)}, {MT(0, in0, "xy")}, {}, ARR()},
922       { TGSI_OPCODE_MOV, {MT(1, 3, WRITEMASK_Y)}, {MT(0, in0, "xx")}, {}, ARR()},
923       { TGSI_OPCODE_MOV, {MT(1, 4, WRITEMASK_XYZ)}, {MT(0, in0, "xyz")}, {}, ARR()},
924       { TGSI_OPCODE_MOV, {MT(1, 5, WRITEMASK_W)}, {MT(0, in0, "xxxx")}, {}, ARR()},
925       { TGSI_OPCODE_MOV, {MT(1, 6, WRITEMASK_XYZW)}, {MT(0, in0, "xyzw")}, {}, ARR()},
926 
927       { TGSI_OPCODE_ADD, {MT(0, out0, WRITEMASK_X)}, {MT(1, 1, "x"), MT(0, in0, "y")}, {}, ARR()},
928       { TGSI_OPCODE_ADD, {MT(0, out0, WRITEMASK_YZ)}, {MT(1, 2, "xy"), MT(0, in0, "yz")}, {}, ARR()},
929       { TGSI_OPCODE_MUL, {MT(0, out0, WRITEMASK_W)}, {MT(1, 3, "y"), MT(0, in0, "xx")}, {}, ARR()},
930       { TGSI_OPCODE_ADD, {MT(0, out1, WRITEMASK_XYZ)}, {MT(1, 4, "xyz"), MT(0, in0, "xyz")}, {}, ARR()},
931       { TGSI_OPCODE_MAD, {MT(0, out1, WRITEMASK_W)}, {MT(1, 5, "w"), MT(1, 1, "yyyy"), MT(1, 1, "xxxx")}, {}, ARR()},
932       { TGSI_OPCODE_ADD, {MT(0, out2, WRITEMASK_XYZW)}, {MT(1, 6, "xyzw"), MT(0, in0, "xyzw")}, {}, ARR()},
933       { TGSI_OPCODE_END}
934    };
935 
936    run(code, expect, array_sizes, remapping);
937 
938 }
939 
run(const vector<FakeCodeline> & code,const vector<FakeCodeline> & expect,vector<unsigned> array_sizes,vector<array_remapping> & remapping) const940 void ArrayRemapTest::run (const vector<FakeCodeline>& code,
941 			  const vector<FakeCodeline>& expect,
942 			  vector<unsigned> array_sizes,
943 			  vector<array_remapping>& remapping) const
944 {
945    FakeShader input(code);
946    FakeShader expect_shader(expect);
947    exec_list *program = input.get_program(mem_ctx);
948 
949    int n_arrays = remap_arrays(array_sizes.size() - 1, &array_sizes[0],
950 	 program, &remapping[0]);
951 
952    EXPECT_EQ(n_arrays, expect_shader.get_num_arrays());
953 
954    FakeShader remapped_program(program);
955 
956    ASSERT_EQ(remapped_program.length(), expect_shader.length());
957 
958    for (size_t i = 0; i < expect_shader.length(); i++) {
959       EXPECT_EQ(remapped_program.line(i), expect_shader.line(i));
960    }
961 
962 }
963