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