1 /*
2 * Copyright © 2022 Pavel Ondračka
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 #include "nir_test.h"
25
26 class nir_opt_shrink_vectors_test : public nir_test {
27 protected:
28 nir_opt_shrink_vectors_test();
29
30 nir_def *in_def;
31 nir_variable *out_var;
32 };
33
nir_opt_shrink_vectors_test()34 nir_opt_shrink_vectors_test::nir_opt_shrink_vectors_test()
35 : nir_test::nir_test("nir_opt_shrink_vectors_test")
36 {
37 nir_variable *var = nir_variable_create(b->shader, nir_var_shader_in, glsl_vec_type(2), "in");
38 in_def = nir_load_var(b, var);
39
40 out_var = nir_variable_create(b->shader, nir_var_shader_out, glsl_vec_type(1), "out");
41 }
42
translate_swizzle(char swz)43 static unsigned translate_swizzle(char swz)
44 {
45 const char *swizzles_dict = "xyzw";
46 const char *extended_swizzles_dict = "abcdefghijklmnop";
47
48 const char *ptr = strchr(swizzles_dict, swz);
49 if (ptr)
50 return ptr - swizzles_dict;
51 else
52 return strchr(extended_swizzles_dict, swz) - extended_swizzles_dict;
53 }
54
set_swizzle(nir_alu_src * src,const char * swizzle)55 static void set_swizzle(nir_alu_src * src, const char * swizzle)
56 {
57 unsigned i = 0;
58 while (swizzle[i]) {
59 src->swizzle[i] = translate_swizzle(swizzle[i]);
60 i++;
61 }
62 }
63
check_swizzle(nir_alu_src * src,const char * swizzle)64 static void check_swizzle(nir_alu_src * src, const char * swizzle)
65 {
66 unsigned i = 0;
67 while (swizzle[i]) {
68 ASSERT_TRUE(src->swizzle[i] == translate_swizzle(swizzle[i]));
69 i++;
70 }
71 }
72
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_vectors_load_const_trailing_component_only)73 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_vectors_load_const_trailing_component_only)
74 {
75 /* Test that opt_shrink_vectors correctly removes unused trailing channels
76 * of load_const.
77 *
78 * vec4 32 ssa_1 = load_const (1.0, 2.0, 3.0, 4.0)
79 * vec1 32 ssa_2 = fmov ssa_1.x
80 *
81 * to
82 *
83 * vec1 32 ssa_1 = load_const (1.0)
84 * vec1 32 ssa_2 = fmov ssa_1.x
85 */
86
87 nir_def *imm_vec = nir_imm_vec4(b, 1.0, 2.0, 3.0, 4.0);
88
89 nir_def *alu_result = nir_build_alu1(b, nir_op_mov, imm_vec);
90 nir_alu_instr *alu_instr = nir_instr_as_alu(alu_result->parent_instr);
91 set_swizzle(&alu_instr->src[0], "x");
92 alu_result->num_components = 1;
93
94 nir_store_var(b, out_var, alu_result, 1);
95
96 ASSERT_TRUE(nir_opt_shrink_vectors(b->shader, true));
97
98 nir_validate_shader(b->shader, NULL);
99
100 ASSERT_TRUE(imm_vec->num_components == 1);
101 nir_load_const_instr * imm_vec_instr = nir_instr_as_load_const(imm_vec->parent_instr);
102 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[0], 32) == 1.0);
103
104 ASSERT_FALSE(nir_opt_shrink_vectors(b->shader, true));
105 }
106
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_vectors_alu_trailing_component_only)107 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_vectors_alu_trailing_component_only)
108 {
109 /* Test that opt_shrink_vectors correctly removes unused trailing channels
110 * of alus.
111 *
112 * vec4 32 ssa_1 = fmov ssa_0.xyzx
113 * vec1 32 ssa_2 = fmov ssa_1.x
114 *
115 * to
116 *
117 * vec1 32 ssa_1 = fmov ssa_0.x
118 * vec1 32 ssa_2 = fmov ssa_1.x
119 */
120
121 nir_def *alu_result = nir_build_alu1(b, nir_op_mov, in_def);
122 nir_alu_instr *alu_instr = nir_instr_as_alu(alu_result->parent_instr);
123 alu_result->num_components = 4;
124 set_swizzle(&alu_instr->src[0], "xyxx");
125
126 nir_def *alu2_result = nir_build_alu1(b, nir_op_mov, alu_result);
127 nir_alu_instr *alu2_instr = nir_instr_as_alu(alu2_result->parent_instr);
128 set_swizzle(&alu2_instr->src[0], "x");
129 alu2_result->num_components = 1;
130
131 nir_store_var(b, out_var, alu2_result, 1);
132
133 ASSERT_TRUE(nir_opt_shrink_vectors(b->shader, true));
134
135 nir_validate_shader(b->shader, NULL);
136
137 check_swizzle(&alu_instr->src[0], "x");
138 ASSERT_TRUE(alu_result->num_components == 1);
139
140 ASSERT_FALSE(nir_opt_shrink_vectors(b->shader, true));
141 }
142
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_vectors_simple)143 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_vectors_simple)
144 {
145 /* Tests that opt_shrink_vectors correctly shrinks a simple case.
146 *
147 * vec4 32 ssa_2 = load_const (3.0, 1.0, 2.0, 1.0)
148 * vec4 32 ssa_3 = fadd ssa_1.xxxy, ssa_2.ywyz
149 * vec1 32 ssa_4 = fdot3 ssa_3.xzw ssa_3.xzw
150 *
151 * to
152 *
153 * vec2 32 ssa_2 = load_const (1.0, 2.0)
154 * vec2 32 ssa_3 = fadd ssa_1, ssa_2
155 * vec1 32 ssa_4 = fdot3 ssa_3.xxy ssa_3.xxy
156 */
157
158 nir_def *imm_vec = nir_imm_vec4(b, 3.0, 1.0, 2.0, 1.0);
159
160 nir_def *alu_result = nir_build_alu2(b, nir_op_fadd, in_def, imm_vec);
161 nir_alu_instr *alu_instr = nir_instr_as_alu(alu_result->parent_instr);
162 alu_result->num_components = 4;
163 set_swizzle(&alu_instr->src[0], "xxxy");
164 set_swizzle(&alu_instr->src[1], "ywyz");
165
166 nir_def *alu2_result = nir_build_alu2(b, nir_op_fdot3, alu_result, alu_result);
167 nir_alu_instr *alu2_instr = nir_instr_as_alu(alu2_result->parent_instr);
168 set_swizzle(&alu2_instr->src[0], "xzw");
169 set_swizzle(&alu2_instr->src[1], "xzw");
170
171 nir_store_var(b, out_var, alu2_result, 1);
172
173 ASSERT_TRUE(nir_opt_shrink_vectors(b->shader, true));
174
175 nir_validate_shader(b->shader, NULL);
176
177 ASSERT_TRUE(imm_vec->num_components == 2);
178 nir_load_const_instr * imm_vec_instr = nir_instr_as_load_const(imm_vec->parent_instr);
179 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[0], 32) == 1.0);
180 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[1], 32) == 2.0);
181
182 ASSERT_TRUE(alu_result->num_components == 2);
183 check_swizzle(&alu_instr->src[0], "xy");
184 check_swizzle(&alu_instr->src[1], "xy");
185
186 check_swizzle(&alu2_instr->src[0], "xxy");
187 check_swizzle(&alu2_instr->src[1], "xxy");
188
189 ASSERT_FALSE(nir_opt_shrink_vectors(b->shader, true));
190
191 nir_validate_shader(b->shader, NULL);
192 }
193
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_vectors_vec8)194 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_vectors_vec8)
195 {
196 /* Tests that opt_shrink_vectors correctly shrinks a case
197 * dealing with vec8 shrinking. The shrinking would result in
198 * vec6 for load const and vec7 for fadd and is therefore not allowed,
199 * but check that we still properly reuse the channels and move
200 * the unused channels to the end.
201 *
202 * vec8 32 ssa_2 = load_const (1.0, 1.0, 2.0, 3.0, 4.0, 5.0, 2.0, 6.0)
203 * vec8 32 ssa_3 = fadd ssa_1.xxxxxxxy, ssa_2.afhdefgh
204 * vec1 32 ssa_4 = fdot8 ssa_3.accdefgh ssa_3.accdefgh
205 *
206 * to
207 *
208 * vec8 32 ssa_2 = load_const (1.0, 3.0, 4.0, 5.0, 2.0, 6.0, .., ..))
209 * vec8 32 ssa_3 = fadd ssa_1.xxxxxxy_ ssa_2.afbcdef_
210 * vec1 32 ssa_4 = fdot8 ssa_3.abbcdefg ssa_3.abbcdefg
211 */
212
213 nir_const_value v[8] = {
214 nir_const_value_for_float(1.0, 32),
215 nir_const_value_for_float(1.0, 32),
216 nir_const_value_for_float(2.0, 32),
217 nir_const_value_for_float(3.0, 32),
218 nir_const_value_for_float(4.0, 32),
219 nir_const_value_for_float(5.0, 32),
220 nir_const_value_for_float(2.0, 32),
221 nir_const_value_for_float(6.0, 32),
222 };
223 nir_def *imm_vec = nir_build_imm(b, 8, 32, v);
224
225 nir_def *alu_result = nir_build_alu2(b, nir_op_fadd, in_def, imm_vec);
226 nir_alu_instr *alu_instr = nir_instr_as_alu(alu_result->parent_instr);
227 alu_result->num_components = 8;
228 set_swizzle(&alu_instr->src[0], "xxxxxxxy");
229 set_swizzle(&alu_instr->src[1], "afhdefgh");
230
231 nir_def *alu2_result = nir_build_alu2(b, nir_op_fdot8, alu_result, alu_result);
232 nir_alu_instr *alu2_instr = nir_instr_as_alu(alu2_result->parent_instr);
233 set_swizzle(&alu2_instr->src[0], "accdefgh");
234 set_swizzle(&alu2_instr->src[1], "accdefgh");
235
236 nir_store_var(b, out_var, alu2_result, 1);
237
238 ASSERT_TRUE(nir_opt_shrink_vectors(b->shader, true));
239
240 nir_validate_shader(b->shader, NULL);
241
242 ASSERT_TRUE(imm_vec->num_components == 8);
243 nir_load_const_instr * imm_vec_instr = nir_instr_as_load_const(imm_vec->parent_instr);
244 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[0], 32) == 1.0);
245 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[1], 32) == 3.0);
246 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[2], 32) == 4.0);
247 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[3], 32) == 5.0);
248 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[4], 32) == 2.0);
249 ASSERT_TRUE(nir_const_value_as_float(imm_vec_instr->value[5], 32) == 6.0);
250
251 ASSERT_TRUE(alu_result->num_components == 8);
252 check_swizzle(&alu_instr->src[0], "xxxxxxy");
253 check_swizzle(&alu_instr->src[1], "afbcdef");
254
255 check_swizzle(&alu2_instr->src[0], "abbcdefg");
256 check_swizzle(&alu2_instr->src[1], "abbcdefg");
257
258 ASSERT_FALSE(nir_opt_shrink_vectors(b->shader, true));
259
260 nir_validate_shader(b->shader, NULL);
261 }
262
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_phis_loop_simple)263 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_phis_loop_simple)
264 {
265 /* Test that the phi is shrinked in the following case.
266 *
267 * v = vec4(0.0, 0.0, 0.0, 0.0);
268 * while (v.y < 3) {
269 * v.y += 1.0;
270 * }
271 *
272 * This mimics nir for loops that come out of nine+ttn.
273 */
274 nir_def *v = nir_imm_vec4(b, 0.0, 0.0, 0.0, 0.0);
275 nir_def *increment = nir_imm_float(b, 1.0);
276 nir_def *loop_max = nir_imm_float(b, 3.0);
277
278 nir_phi_instr *const phi = nir_phi_instr_create(b->shader);
279 nir_def *phi_def = &phi->def;
280
281 nir_loop *loop = nir_push_loop(b);
282
283 nir_def_init(&phi->instr, &phi->def, v->num_components, v->bit_size);
284
285 nir_phi_instr_add_src(phi, v->parent_instr->block, v);
286
287 nir_def *fge = nir_fge(b, phi_def, loop_max);
288 nir_alu_instr *fge_alu_instr = nir_instr_as_alu(fge->parent_instr);
289 fge->num_components = 1;
290 fge_alu_instr->src[0].swizzle[0] = 1;
291
292 nir_if *nif = nir_push_if(b, fge);
293 {
294 nir_jump_instr *jump = nir_jump_instr_create(b->shader, nir_jump_break);
295 nir_builder_instr_insert(b, &jump->instr);
296 }
297 nir_pop_if(b, nif);
298
299 nir_def *fadd = nir_fadd(b, phi_def, increment);
300 nir_alu_instr *fadd_alu_instr = nir_instr_as_alu(fadd->parent_instr);
301 fadd->num_components = 1;
302 fadd_alu_instr->src[0].swizzle[0] = 1;
303
304 nir_scalar srcs[4] = {{0}};
305 for (unsigned i = 0; i < 4; i++) {
306 srcs[i] = nir_get_scalar(phi_def, i);
307 }
308 srcs[1] = nir_get_scalar(fadd, 0);
309 nir_def *vec = nir_vec_scalars(b, srcs, 4);
310
311 nir_phi_instr_add_src(phi, vec->parent_instr->block, vec);
312
313 nir_pop_loop(b, loop);
314
315 b->cursor = nir_before_block(nir_loop_first_block(loop));
316 nir_builder_instr_insert(b, &phi->instr);
317
318 /* Generated nir:
319 *
320 * impl main {
321 * block block_0:
322 * * preds: *
323 * vec1 32 ssa_0 = deref_var &in (shader_in vec2)
324 * vec2 32 ssa_1 = intrinsic load_deref (ssa_0) (access=0)
325 * vec4 32 ssa_2 = load_const (0x00000000, 0x00000000, 0x00000000, 0x00000000) = (0.000000, 0.000000, 0.000000, 0.000000)
326 * vec1 32 ssa_3 = load_const (0x3f800000 = 1.000000)
327 * vec1 32 ssa_4 = load_const (0x40400000 = 3.000000)
328 * * succs: block_1 *
329 * loop {
330 * block block_1:
331 * * preds: block_0 block_4 *
332 * vec4 32 ssa_8 = phi block_0: ssa_2, block_4: ssa_7
333 * vec1 1 ssa_5 = fge ssa_8.y, ssa_4
334 * * succs: block_2 block_3 *
335 * if ssa_5 {
336 * block block_2:
337 * * preds: block_1 *
338 * break
339 * * succs: block_5 *
340 * } else {
341 * block block_3:
342 * * preds: block_1 *
343 * * succs: block_4 *
344 * }
345 * block block_4:
346 * * preds: block_3 *
347 * vec1 32 ssa_6 = fadd ssa_8.y, ssa_3
348 * vec4 32 ssa_7 = vec4 ssa_8.x, ssa_6, ssa_8.z, ssa_8.w
349 * * succs: block_1 *
350 * }
351 * block block_5:
352 * * preds: block_2 *
353 * * succs: block_6 *
354 * block block_6:
355 * }
356 */
357
358 nir_validate_shader(b->shader, NULL);
359
360 ASSERT_TRUE(nir_opt_shrink_vectors(b->shader, true));
361 ASSERT_TRUE(phi_def->num_components == 1);
362 check_swizzle(&fge_alu_instr->src[0], "x");
363 check_swizzle(&fadd_alu_instr->src[0], "x");
364
365 nir_validate_shader(b->shader, NULL);
366 }
367
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_phis_loop_swizzle)368 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_phis_loop_swizzle)
369 {
370 /* Test that the phi is shrinked properly in the following case where
371 * some swizzling happens in the channels.
372 *
373 * v = vec4(0.0, 0.0, 0.0, 0.0);
374 * while (v.z < 3) {
375 * v = vec4(v.x, v.z + 1, v.y, v.w};
376 * }
377 */
378 nir_def *v = nir_imm_vec4(b, 0.0, 0.0, 0.0, 0.0);
379 nir_def *increment = nir_imm_float(b, 1.0);
380 nir_def *loop_max = nir_imm_float(b, 3.0);
381
382 nir_phi_instr *const phi = nir_phi_instr_create(b->shader);
383 nir_def *phi_def = &phi->def;
384
385 nir_loop *loop = nir_push_loop(b);
386
387 nir_def_init(&phi->instr, &phi->def, v->num_components, v->bit_size);
388
389 nir_phi_instr_add_src(phi, v->parent_instr->block, v);
390
391 nir_def *fge = nir_fge(b, phi_def, loop_max);
392 nir_alu_instr *fge_alu_instr = nir_instr_as_alu(fge->parent_instr);
393 fge->num_components = 1;
394 fge_alu_instr->src[0].swizzle[0] = 2;
395
396 nir_if *nif = nir_push_if(b, fge);
397
398 nir_jump_instr *jump = nir_jump_instr_create(b->shader, nir_jump_break);
399 nir_builder_instr_insert(b, &jump->instr);
400
401 nir_pop_if(b, nif);
402
403 nir_def *fadd = nir_fadd(b, phi_def, increment);
404 nir_alu_instr *fadd_alu_instr = nir_instr_as_alu(fadd->parent_instr);
405 fadd->num_components = 1;
406 fadd_alu_instr->src[0].swizzle[0] = 2;
407
408 nir_scalar srcs[4] = {{0}};
409 srcs[0] = nir_get_scalar(phi_def, 0);
410 srcs[1] = nir_get_scalar(fadd, 0);
411 srcs[2] = nir_get_scalar(phi_def, 1);
412 srcs[3] = nir_get_scalar(phi_def, 3);
413 nir_def *vec = nir_vec_scalars(b, srcs, 4);
414
415 nir_phi_instr_add_src(phi, vec->parent_instr->block, vec);
416
417 nir_pop_loop(b, loop);
418
419 b->cursor = nir_before_block(nir_loop_first_block(loop));
420 nir_builder_instr_insert(b, &phi->instr);
421
422 /* Generated nir:
423 *
424 * impl main {
425 * block block_0:
426 * * preds: *
427 * vec1 32 ssa_0 = deref_var &in (shader_in vec2)
428 * vec2 32 ssa_1 = intrinsic load_deref (ssa_0) (access=0)
429 * vec4 32 ssa_2 = load_const (0x00000000, 0x00000000, 0x00000000, 0x00000000) = (0.000000, 0.000000, 0.000000, 0.000000)
430 * vec1 32 ssa_3 = load_const (0x3f800000 = 1.000000)
431 * vec1 32 ssa_4 = load_const (0x40400000 = 3.000000)
432 * * succs: block_1 *
433 * loop {
434 * block block_1:
435 * * preds: block_0 block_4 *
436 * vec4 32 ssa_8 = phi block_0: ssa_2, block_4: ssa_7
437 * vec1 1 ssa_5 = fge ssa_8.z, ssa_4
438 * * succs: block_2 block_3 *
439 * if ssa_5 {
440 * block block_2:
441 * * preds: block_1 *
442 * break
443 * * succs: block_5 *
444 * } else {
445 * block block_3:
446 * * preds: block_1 *
447 * * succs: block_4 *
448 * }
449 * block block_4:
450 * * preds: block_3 *
451 * vec1 32 ssa_6 = fadd ssa_8.z, ssa_3
452 * vec4 32 ssa_7 = vec4 ssa_8.x, ssa_6, ssa_8.y, ssa_8.w
453 * * succs: block_1 *
454 * }
455 * block block_5:
456 * * preds: block_2 *
457 * * succs: block_6 *
458 * block block_6:
459 * }
460 */
461
462 nir_validate_shader(b->shader, NULL);
463
464 ASSERT_TRUE(nir_opt_shrink_vectors(b->shader, true));
465 ASSERT_TRUE(phi_def->num_components == 2);
466
467 check_swizzle(&fge_alu_instr->src[0], "y");
468 check_swizzle(&fadd_alu_instr->src[0], "y");
469
470 nir_validate_shader(b->shader, NULL);
471 }
472
TEST_F(nir_opt_shrink_vectors_test,opt_shrink_phis_loop_phi_out)473 TEST_F(nir_opt_shrink_vectors_test, opt_shrink_phis_loop_phi_out)
474 {
475 /* Test that the phi is not shrinked when used by intrinsic.
476 *
477 * v = vec4(0.0, 0.0, 0.0, 0.0);
478 * while (v.y < 3) {
479 * v.y += 1.0;
480 * }
481 * out = v;
482 */
483 nir_def *v = nir_imm_vec4(b, 0.0, 0.0, 0.0, 0.0);
484 nir_def *increment = nir_imm_float(b, 1.0);
485 nir_def *loop_max = nir_imm_float(b, 3.0);
486
487 nir_phi_instr *const phi = nir_phi_instr_create(b->shader);
488 nir_def *phi_def = &phi->def;
489
490 nir_loop *loop = nir_push_loop(b);
491
492 nir_def_init(&phi->instr, &phi->def, v->num_components, v->bit_size);
493
494 nir_phi_instr_add_src(phi, v->parent_instr->block, v);
495
496 nir_def *fge = nir_fge(b, phi_def, loop_max);
497 nir_alu_instr *fge_alu_instr = nir_instr_as_alu(fge->parent_instr);
498 fge->num_components = 1;
499 fge_alu_instr->src[0].swizzle[0] = 1;
500
501 nir_if *nif = nir_push_if(b, fge);
502 {
503 nir_jump_instr *jump = nir_jump_instr_create(b->shader, nir_jump_break);
504 nir_builder_instr_insert(b, &jump->instr);
505 }
506 nir_pop_if(b, nif);
507
508 nir_def *fadd = nir_fadd(b, phi_def, increment);
509 nir_alu_instr *fadd_alu_instr = nir_instr_as_alu(fadd->parent_instr);
510 fadd->num_components = 1;
511 fadd_alu_instr->src[0].swizzle[0] = 1;
512
513 nir_scalar srcs[4] = {{0}};
514 for (unsigned i = 0; i < 4; i++) {
515 srcs[i] = nir_get_scalar(phi_def, i);
516 }
517 srcs[1] = nir_get_scalar(fadd, 0);
518 nir_def *vec = nir_vec_scalars(b, srcs, 4);
519
520 nir_phi_instr_add_src(phi, vec->parent_instr->block, vec);
521
522 nir_pop_loop(b, loop);
523
524 out_var = nir_variable_create(b->shader,
525 nir_var_shader_out,
526 glsl_vec_type(4), "out4");
527
528 nir_store_var(b, out_var, phi_def, BITFIELD_MASK(4));
529
530 b->cursor = nir_before_block(nir_loop_first_block(loop));
531 nir_builder_instr_insert(b, &phi->instr);
532
533 /* Generated nir:
534 *
535 * impl main {
536 * block block_0:
537 * * preds: *
538 * vec1 32 ssa_0 = deref_var &in (shader_in vec2)
539 * vec2 32 ssa_1 = intrinsic load_deref (ssa_0) (access=0)
540 * vec4 32 ssa_2 = load_const (0x00000000, 0x00000000, 0x00000000, 0x00000000) = (0.000000, 0.000000, 0.000000, 0.000000)
541 * vec1 32 ssa_3 = load_const (0x3f800000 = 1.000000)
542 * vec1 32 ssa_4 = load_const (0x40400000 = 3.000000)
543 * * succs: block_1 *
544 * loop {
545 * block block_1:
546 * * preds: block_0 block_4 *
547 * vec4 32 ssa_9 = phi block_0: ssa_2, block_4: ssa_7
548 * vec1 1 ssa_5 = fge ssa_9.y, ssa_4
549 * * succs: block_2 block_3 *
550 * if ssa_5 {
551 * block block_2:
552 * * preds: block_1 *
553 * break
554 * * succs: block_5 *
555 * } else {
556 * block block_3:
557 * * preds: block_1 *
558 * * succs: block_4 *
559 * }
560 * block block_4:
561 * * preds: block_3 *
562 * vec1 32 ssa_6 = fadd ssa_9.y, ssa_3
563 * vec4 32 ssa_7 = vec4 ssa_9.x, ssa_6, ssa_9.z, ssa_9.w
564 * * succs: block_1 *
565 * }
566 * block block_5:
567 * * preds: block_2 *
568 * vec1 32 ssa_8 = deref_var &out4 (shader_out vec4)
569 * intrinsic store_deref (ssa_8, ssa_9) (wrmask=xyzw *15*, access=0)
570 * * succs: block_6 *
571 * block block_6:
572 * }
573 */
574
575 nir_validate_shader(b->shader, NULL);
576
577 ASSERT_FALSE(nir_opt_shrink_vectors(b->shader, true));
578 ASSERT_TRUE(phi_def->num_components == 4);
579 }
580