1/*
2 * Copyright © 2019 Intel Corporation
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#include <gtest/gtest.h>
24#include "nir.h"
25#include "nir_builder.h"
26
27class comparison_pre_test : public ::testing::Test {
28protected:
29   comparison_pre_test()
30   {
31      glsl_type_singleton_init_or_ref();
32
33      static const nir_shader_compiler_options options = { };
34      bld = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, &options,
35                                           "comparison test");
36
37      v1 = nir_imm_vec4(&bld, -2.0, -1.0,  1.0,  2.0);
38      v2 = nir_imm_vec4(&bld,  2.0,  1.0, -1.0, -2.0);
39      v3 = nir_imm_vec4(&bld,  3.0,  4.0,  5.0,  6.0);
40   }
41
42   ~comparison_pre_test()
43   {
44      ralloc_free(bld.shader);
45      glsl_type_singleton_decref();
46   }
47
48   struct nir_builder bld;
49
50   nir_ssa_def *v1;
51   nir_ssa_def *v2;
52   nir_ssa_def *v3;
53
54   const uint8_t xxxx[4] = { 0, 0, 0, 0 };
55   const uint8_t wwww[4] = { 3, 3, 3, 3 };
56};
57
58TEST_F(comparison_pre_test, a_lt_b_vs_neg_a_plus_b)
59{
60   /* Before:
61    *
62    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
63    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
64    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
65    * vec1 32 ssa_3 = load_const ( 1.0)
66    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
67    * vec1 32 ssa_5 = mov ssa_4.x
68    * vec1 1 ssa_6 = flt ssa_5, ssa_3
69    *
70    * if ssa_6 {
71    *    vec1 32 ssa_7 = fneg ssa_5
72    *    vec1 32 ssa_8 = fadd ssa_7, ssa_3
73    * } else {
74    * }
75    *
76    * After:
77    *
78    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
79    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
80    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
81    * vec1 32 ssa_3 = load_const ( 1.0)
82    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
83    * vec1 32 ssa_5 = mov ssa_4.x
84    * vec1 32 ssa_9 = fneg ssa_5
85    * vec1 32 ssa_10 = fadd ssa_3, ssa_9
86    * vec1 32 ssa_11 = load_const (0.0)
87    * vec1 1 ssa_12 = flt ssa_11, ssa_10
88    * vec1 32 ssa_13 = mov ssa_10
89    * vec1 1 ssa_14 = mov ssa_12
90    *
91    * if ssa_14 {
92    *    vec1 32 ssa_7 = fneg ssa_5
93    * } else {
94    * }
95    */
96   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
97   nir_ssa_def *a = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
98
99   nir_ssa_def *flt = nir_flt(&bld, a, one);
100
101   nir_if *nif = nir_push_if(&bld, flt);
102
103   nir_fadd(&bld, nir_fneg(&bld, a), one);
104
105   nir_pop_if(&bld, nif);
106
107   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
108}
109
110TEST_F(comparison_pre_test, a_lt_b_vs_a_minus_b)
111{
112   /* Before:
113    *
114    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
115    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
116    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
117    * vec1 32 ssa_3 = load_const ( 1.0)
118    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
119    * vec1 32 ssa_5 = mov ssa_4.x
120    * vec1 1 ssa_6 = flt ssa_3, ssa_5
121    *
122    * if ssa_6 {
123    *    vec1 32 ssa_7 = fneg ssa_5
124    *    vec1 32 ssa_8 = fadd ssa_3, ssa_7
125    * } else {
126    * }
127    *
128    * After:
129    *
130    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
131    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
132    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
133    * vec1 32 ssa_3 = load_const ( 1.0)
134    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
135    * vec1 32 ssa_5 = mov ssa_4.x
136    * vec1 32 ssa_9 = fneg ssa_5
137    * vec1 32 ssa_10 = fadd ssa_3, ssa_9
138    * vec1 32 ssa_11 = load_const (0.0)
139    * vec1 1 ssa_12 = flt ssa_10, ssa_11
140    * vec1 32 ssa_13 = mov ssa_10
141    * vec1 1 ssa_14 = mov ssa_12
142    *
143    * if ssa_14 {
144    *    vec1 32 ssa_7 = fneg ssa_5
145    * } else {
146    * }
147    */
148   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
149   nir_ssa_def *b = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
150
151   nir_ssa_def *flt = nir_flt(&bld, one, b);
152
153   nir_if *nif = nir_push_if(&bld, flt);
154
155   nir_fadd(&bld, one, nir_fneg(&bld, b));
156
157   nir_pop_if(&bld, nif);
158
159   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
160}
161
162TEST_F(comparison_pre_test, neg_a_lt_b_vs_a_plus_b)
163{
164   /* Before:
165    *
166    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
167    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
168    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
169    * vec1 32 ssa_3 = load_const ( 1.0)
170    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
171    * vec1 32 ssa_5 = mov ssa_4.x
172    * vec1 32 ssa_6 = fneg ssa_5
173    * vec1 1 ssa_7 = flt ssa_6, ssa_3
174    *
175    * if ssa_7 {
176    *    vec1 32 ssa_8 = fadd ssa_5, ssa_3
177    * } else {
178    * }
179    *
180    * After:
181    *
182    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
183    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
184    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
185    * vec1 32 ssa_3 = load_const ( 1.0)
186    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
187    * vec1 32 ssa_5 = mov ssa_4.x
188    * vec1 32 ssa_9 = fneg ssa_5
189    * vec1 32 ssa_9 = fneg ssa_6
190    * vec1 32 ssa_10 = fadd ssa_3, ssa_9
191    * vec1 32 ssa_11 = load_const ( 0.0)
192    * vec1 1 ssa_12 = flt ssa_11, ssa_10
193    * vec1 32 ssa_13 = mov ssa_10
194    * vec1 1 ssa_14 = mov ssa_12
195    *
196    * if ssa_14 {
197    * } else {
198    * }
199    */
200
201   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
202   nir_ssa_def *a = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
203
204   nir_ssa_def *flt = nir_flt(&bld, nir_fneg(&bld, a), one);
205
206   nir_if *nif = nir_push_if(&bld, flt);
207
208   nir_fadd(&bld, a, one);
209
210   nir_pop_if(&bld, nif);
211
212   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
213}
214
215TEST_F(comparison_pre_test, a_lt_neg_b_vs_a_plus_b)
216{
217   /* Before:
218    *
219    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
220    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
221    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
222    * vec1 32 ssa_3 = load_const ( 1.0)
223    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
224    * vec1 32 ssa_5 = mov ssa_4.x
225    * vec1 32 ssa_6 = fneg ssa_5
226    * vec1 1 ssa_7 = flt ssa_3, ssa_6
227    *
228    * if ssa_7 {
229    *    vec1 32 ssa_8 = fadd ssa_3, ssa_5
230    * } else {
231    * }
232    *
233    * After:
234    *
235    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
236    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
237    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
238    * vec1 32 ssa_3 = load_const ( 1.0)
239    * vec4 32 ssa_4 = fadd ssa_0, ssa_2
240    * vec1 32 ssa_5 = mov ssa_4.x
241    * vec1 32 ssa_9 = fneg ssa_5
242    * vec1 32 ssa_9 = fneg ssa_6
243    * vec1 32 ssa_10 = fadd ssa_3, ssa_9
244    * vec1 32 ssa_11 = load_const ( 0.0)
245    * vec1 1 ssa_12 = flt ssa_10, ssa_11
246    * vec1 32 ssa_13 = mov ssa_10
247    * vec1 1 ssa_14 = mov ssa_12
248    *
249    * if ssa_14 {
250    * } else {
251    * }
252    */
253   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
254   nir_ssa_def *b = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
255
256   nir_ssa_def *flt = nir_flt(&bld, one, nir_fneg(&bld, b));
257
258   nir_if *nif = nir_push_if(&bld, flt);
259
260   nir_fadd(&bld, one, b);
261
262   nir_pop_if(&bld, nif);
263
264   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
265}
266
267TEST_F(comparison_pre_test, imm_lt_b_vs_neg_imm_plus_b)
268{
269   /* Before:
270    *
271    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
272    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
273    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
274    * vec1 32 ssa_3 = load_const ( 1.0)
275    * vec1 32 ssa_4 = load_const (-1.0)
276    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
277    * vec1 32 ssa_6 = mov ssa_5.x
278    * vec1 1 ssa_7 = flt ssa_3, ssa_6
279    *
280    * if ssa_7 {
281    *    vec1 32 ssa_8 = fadd ssa_4, ssa_6
282    * } else {
283    * }
284    *
285    * After:
286    *
287    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
288    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
289    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
290    * vec1 32 ssa_3 = load_const ( 1.0)
291    * vec1 32 ssa_4 = load_const (-1.0)
292    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
293    * vec1 32 ssa_6 = mov ssa_5.x
294    * vec1 32 ssa_9 = fneg ssa_3
295    * vec1 32 ssa_10 = fadd ssa_6, ssa_9
296    * vec1 32 ssa_11 = load_const ( 0.0)
297    * vec1 1 ssa_12 = flt ssa_11, ssa_10
298    * vec1 32 ssa_13 = mov ssa_10
299    * vec1 1 ssa_14 = mov ssa_12
300    *
301    * if ssa_14 {
302    * } else {
303    * }
304    */
305   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
306   nir_ssa_def *neg_one = nir_imm_float(&bld, -1.0f);
307   nir_ssa_def *a = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
308
309   nir_ssa_def *flt = nir_flt(&bld, one, a);
310
311   nir_if *nif = nir_push_if(&bld, flt);
312
313   nir_fadd(&bld, neg_one, a);
314
315   nir_pop_if(&bld, nif);
316
317   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
318}
319
320TEST_F(comparison_pre_test, a_lt_imm_vs_a_minus_imm)
321{
322   /* Before:
323    *
324    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
325    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
326    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
327    * vec1 32 ssa_3 = load_const ( 1.0)
328    * vec1 32 ssa_4 = load_const (-1.0)
329    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
330    * vec1 32 ssa_6 = mov ssa_5.x
331    * vec1 1 ssa_7 = flt ssa_6, ssa_3
332    *
333    * if ssa_6 {
334    *    vec1 32 ssa_8 = fadd ssa_6, ssa_4
335    * } else {
336    * }
337    *
338    * After:
339    *
340    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
341    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
342    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
343    * vec1 32 ssa_3 = load_const ( 1.0)
344    * vec1 32 ssa_4 = load_const (-1.0)
345    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
346    * vec1 32 ssa_6 = mov ssa_5.x
347    * vec1 32 ssa_9 = fneg ssa_3
348    * vec1 32 ssa_10 = fadd ssa_6, ssa_9
349    * vec1 32 ssa_11 = load_const ( 0.0)
350    * vec1 1 ssa_12 = flt ssa_10, ssa_11
351    * vec1 32 ssa_13 = mov ssa_10
352    * vec1 1 ssa_14 = mov ssa_12
353    *
354    * if ssa_14 {
355    * } else {
356    * }
357    */
358   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
359   nir_ssa_def *neg_one = nir_imm_float(&bld, -1.0f);
360   nir_ssa_def *a = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
361
362   nir_ssa_def *flt = nir_flt(&bld, a, one);
363
364   nir_if *nif = nir_push_if(&bld, flt);
365
366   nir_fadd(&bld, a, neg_one);
367
368   nir_pop_if(&bld, nif);
369
370   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
371}
372
373TEST_F(comparison_pre_test, neg_imm_lt_a_vs_a_plus_imm)
374{
375   /* Before:
376    *
377    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
378    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
379    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
380    * vec1 32 ssa_3 = load_const ( 1.0)
381    * vec1 32 ssa_4 = load_const (-1.0)
382    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
383    * vec1 32 ssa_6 = mov ssa_5.x
384    * vec1 1 ssa_7 = flt ssa_4, ssa_6
385    *
386    * if ssa_7 {
387    *    vec1 32 ssa_8 = fadd ssa_6, ssa_3
388    * } else {
389    * }
390    *
391    * After:
392    *
393    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
394    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
395    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
396    * vec1 32 ssa_3 = load_const ( 1.0)
397    * vec1 32 ssa_4 = load_const (-1.0)
398    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
399    * vec1 32 ssa_6 = mov ssa_5.x
400    * vec1 32 ssa_9 = fneg ssa_4
401    * vec1 32 ssa_10 = fadd ssa_6, ssa_9
402    * vec1 32 ssa_11 = load_const ( 0.0)
403    * vec1 1 ssa_12 = flt ssa_11, ssa_10
404    * vec1 32 ssa_13 = mov ssa_10
405    * vec1 1 ssa_14 = mov ssa_12
406    *
407    * if ssa_14 {
408    * } else {
409    * }
410    */
411
412   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
413   nir_ssa_def *neg_one = nir_imm_float(&bld, -1.0f);
414   nir_ssa_def *a = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
415
416   nir_ssa_def *flt = nir_flt(&bld, neg_one, a);
417
418   nir_if *nif = nir_push_if(&bld, flt);
419
420   nir_fadd(&bld, a, one);
421
422   nir_pop_if(&bld, nif);
423
424   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
425}
426
427TEST_F(comparison_pre_test, a_lt_neg_imm_vs_a_plus_imm)
428{
429   /* Before:
430    *
431    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
432    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
433    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
434    * vec1 32 ssa_3 = load_const ( 1.0)
435    * vec1 32 ssa_4 = load_const (-1.0)
436    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
437    * vec1 32 ssa_6 = mov ssa_5.x
438    * vec1 1 ssa_7 = flt ssa_6, ssa_4
439    *
440    * if ssa_7 {
441    *    vec1 32 ssa_8 = fadd ssa_6, ssa_3
442    * } else {
443    * }
444    *
445    * After:
446    *
447    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
448    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
449    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
450    * vec1 32 ssa_3 = load_const ( 1.0)
451    * vec1 32 ssa_4 = load_const (-1.0)
452    * vec4 32 ssa_5 = fadd ssa_0, ssa_2
453    * vec1 32 ssa_6 = mov ssa_5.x
454    * vec1 32 ssa_9 = fneg ssa_4
455    * vec1 32 ssa_10 = fadd ssa_6, ssa_9
456    * vec1 32 ssa_11 = load_const ( 0.0)
457    * vec1 1 ssa_12 = flt ssa_10, ssa_11
458    * vec1 32 ssa_13 = mov ssa_10
459    * vec1 1 ssa_14 = mov ssa_12
460    *
461    * if ssa_14 {
462    * } else {
463    * }
464    */
465   nir_ssa_def *one = nir_imm_float(&bld, 1.0f);
466   nir_ssa_def *neg_one = nir_imm_float(&bld, -1.0f);
467   nir_ssa_def *a = nir_channel(&bld, nir_fadd(&bld, v1, v3), 0);
468
469   nir_ssa_def *flt = nir_flt(&bld, a, neg_one);
470
471   nir_if *nif = nir_push_if(&bld, flt);
472
473   nir_fadd(&bld, a, one);
474
475   nir_pop_if(&bld, nif);
476
477   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
478}
479
480TEST_F(comparison_pre_test, swizzle_of_same_immediate_vector)
481{
482   /* Before:
483    *
484    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
485    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
486    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
487    * vec4 32 ssa_3 = fadd ssa_0, ssa_2
488    * vec1 1 ssa_4 = flt ssa_0.x, ssa_3.x
489    *
490    * if ssa_4 {
491    *    vec1 32 ssa_5 = fadd ssa_0.w, ssa_3.x
492    * } else {
493    * }
494    */
495   nir_ssa_def *a = nir_fadd(&bld, v1, v3);
496
497   nir_alu_instr *flt = nir_alu_instr_create(bld.shader, nir_op_flt);
498
499   flt->src[0].src = nir_src_for_ssa(v1);
500   flt->src[1].src = nir_src_for_ssa(a);
501
502   memcpy(&flt->src[0].swizzle, xxxx, sizeof(xxxx));
503   memcpy(&flt->src[1].swizzle, xxxx, sizeof(xxxx));
504
505   nir_builder_alu_instr_finish_and_insert(&bld, flt);
506
507   flt->dest.dest.ssa.num_components = 1;
508   flt->dest.write_mask = 1;
509
510   nir_if *nif = nir_push_if(&bld, &flt->dest.dest.ssa);
511
512   nir_alu_instr *fadd = nir_alu_instr_create(bld.shader, nir_op_fadd);
513
514   fadd->src[0].src = nir_src_for_ssa(v1);
515   fadd->src[1].src = nir_src_for_ssa(a);
516
517   memcpy(&fadd->src[0].swizzle, wwww, sizeof(wwww));
518   memcpy(&fadd->src[1].swizzle, xxxx, sizeof(xxxx));
519
520   nir_builder_alu_instr_finish_and_insert(&bld, fadd);
521
522   fadd->dest.dest.ssa.num_components = 1;
523   fadd->dest.write_mask = 1;
524
525   nir_pop_if(&bld, nif);
526
527   EXPECT_TRUE(nir_opt_comparison_pre_impl(bld.impl));
528}
529
530TEST_F(comparison_pre_test, non_scalar_add_result)
531{
532   /* The optimization pass should not do anything because the result of the
533    * fadd is not a scalar.
534    *
535    * Before:
536    *
537    * vec4 32 ssa_0 = load_const (-2.0, -1.0,  1.0,  2.0)
538    * vec4 32 ssa_1 = load_const ( 2.0,  1.0, -1.0, -2.0)
539    * vec4 32 ssa_2 = load_const ( 3.0,  4.0,  5.0,  6.0)
540    * vec4 32 ssa_3 = fadd ssa_0, ssa_2
541    * vec1 1 ssa_4 = flt ssa_0.x, ssa_3.x
542    *
543    * if ssa_4 {
544    *    vec2 32 ssa_5 = fadd ssa_1.xx, ssa_3.xx
545    * } else {
546    * }
547    *
548    * After:
549    *
550    * No change.
551    */
552   nir_ssa_def *a = nir_fadd(&bld, v1, v3);
553
554   nir_alu_instr *flt = nir_alu_instr_create(bld.shader, nir_op_flt);
555
556   flt->src[0].src = nir_src_for_ssa(v1);
557   flt->src[1].src = nir_src_for_ssa(a);
558
559   memcpy(&flt->src[0].swizzle, xxxx, sizeof(xxxx));
560   memcpy(&flt->src[1].swizzle, xxxx, sizeof(xxxx));
561
562   nir_builder_alu_instr_finish_and_insert(&bld, flt);
563
564   flt->dest.dest.ssa.num_components = 1;
565   flt->dest.write_mask = 1;
566
567   nir_if *nif = nir_push_if(&bld, &flt->dest.dest.ssa);
568
569   nir_alu_instr *fadd = nir_alu_instr_create(bld.shader, nir_op_fadd);
570
571   fadd->src[0].src = nir_src_for_ssa(v2);
572   fadd->src[1].src = nir_src_for_ssa(a);
573
574   memcpy(&fadd->src[0].swizzle, xxxx, sizeof(xxxx));
575   memcpy(&fadd->src[1].swizzle, xxxx, sizeof(xxxx));
576
577   nir_builder_alu_instr_finish_and_insert(&bld, fadd);
578
579   fadd->dest.dest.ssa.num_components = 2;
580   fadd->dest.write_mask = 3;
581
582   nir_pop_if(&bld, nif);
583
584   EXPECT_FALSE(nir_opt_comparison_pre_impl(bld.impl));
585}
586