xref: /aosp_15_r20/external/mesa3d/src/compiler/nir/tests/negative_equal_tests.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2018 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 #include "util/half_float.h"
27 
28 static void count_sequence(nir_const_value c[NIR_MAX_VEC_COMPONENTS],
29                            nir_alu_type full_type, int first);
30 static void negate(nir_const_value dst[NIR_MAX_VEC_COMPONENTS],
31                    const nir_const_value src[NIR_MAX_VEC_COMPONENTS],
32                    nir_alu_type full_type, unsigned components);
33 
34 class const_value_negative_equal_test : public ::testing::Test {
35 protected:
const_value_negative_equal_test()36    const_value_negative_equal_test()
37    {
38       glsl_type_singleton_init_or_ref();
39 
40       memset(c1, 0, sizeof(c1));
41       memset(c2, 0, sizeof(c2));
42    }
43 
~const_value_negative_equal_test()44    ~const_value_negative_equal_test()
45    {
46       glsl_type_singleton_decref();
47    }
48 
49    nir_const_value c1[NIR_MAX_VEC_COMPONENTS];
50    nir_const_value c2[NIR_MAX_VEC_COMPONENTS];
51 };
52 
53 class alu_srcs_negative_equal_test : public ::testing::Test {
54 protected:
alu_srcs_negative_equal_test()55    alu_srcs_negative_equal_test()
56    {
57       glsl_type_singleton_init_or_ref();
58 
59       static const nir_shader_compiler_options options = { };
60       bld = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, &options,
61                                            "negative equal tests");
62       memset(c1, 0, sizeof(c1));
63       memset(c2, 0, sizeof(c2));
64    }
65 
~alu_srcs_negative_equal_test()66    ~alu_srcs_negative_equal_test()
67    {
68       ralloc_free(bld.shader);
69       glsl_type_singleton_decref();
70    }
71 
72    struct nir_builder bld;
73    nir_const_value c1[NIR_MAX_VEC_COMPONENTS];
74    nir_const_value c2[NIR_MAX_VEC_COMPONENTS];
75 };
76 
TEST_F(const_value_negative_equal_test,float32_zero)77 TEST_F(const_value_negative_equal_test, float32_zero)
78 {
79    /* Verify that 0.0 negative-equals 0.0. */
80    EXPECT_TRUE(nir_const_value_negative_equal(c1[0], c1[0], nir_type_float32));
81 }
82 
TEST_F(const_value_negative_equal_test,float64_zero)83 TEST_F(const_value_negative_equal_test, float64_zero)
84 {
85    /* Verify that 0.0 negative-equals 0.0. */
86    EXPECT_TRUE(nir_const_value_negative_equal(c1[0], c1[0], nir_type_float64));
87 }
88 
89 /* Compare an object with non-zero values to itself.  This should always be
90  * false.
91  */
92 #define compare_with_self(full_type)                                    \
93 TEST_F(const_value_negative_equal_test, full_type ## _self)             \
94 {                                                                       \
95    count_sequence(c1, full_type, 1);                                    \
96    EXPECT_FALSE(nir_const_value_negative_equal(c1[0], c1[0], full_type)); \
97 }
98 
99 compare_with_self(nir_type_float16)
compare_with_self(nir_type_float32)100 compare_with_self(nir_type_float32)
101 compare_with_self(nir_type_float64)
102 compare_with_self(nir_type_int8)
103 compare_with_self(nir_type_uint8)
104 compare_with_self(nir_type_int16)
105 compare_with_self(nir_type_uint16)
106 compare_with_self(nir_type_int32)
107 compare_with_self(nir_type_uint32)
108 compare_with_self(nir_type_int64)
109 compare_with_self(nir_type_uint64)
110 #undef compare_with_self
111 
112 /* Compare an object with the negation of itself.  This should always be true.
113  */
114 #define compare_with_negation(full_type)                                \
115 TEST_F(const_value_negative_equal_test, full_type ## _trivially_true)   \
116 {                                                                       \
117    count_sequence(c1, full_type, 1);                                    \
118    negate(c2, c1, full_type, 1);                                        \
119    EXPECT_TRUE(nir_const_value_negative_equal(c1[0], c2[0], full_type)); \
120 }
121 
122 compare_with_negation(nir_type_float16)
123 compare_with_negation(nir_type_float32)
124 compare_with_negation(nir_type_float64)
125 compare_with_negation(nir_type_int8)
126 compare_with_negation(nir_type_uint8)
127 compare_with_negation(nir_type_int16)
128 compare_with_negation(nir_type_uint16)
129 compare_with_negation(nir_type_int32)
130 compare_with_negation(nir_type_uint32)
131 compare_with_negation(nir_type_int64)
132 compare_with_negation(nir_type_uint64)
133 #undef compare_with_negation
134 
135 TEST_F(alu_srcs_negative_equal_test, trivial_float)
136 {
137    nir_def *two = nir_imm_float(&bld, 2.0f);
138    nir_def *negative_two = nir_imm_float(&bld, -2.0f);
139 
140    nir_def *result = nir_fadd(&bld, two, negative_two);
141    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);
142 
143    ASSERT_NE((void *) 0, instr);
144    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));
145    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 0));
146    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 1));
147 }
148 
TEST_F(alu_srcs_negative_equal_test,trivial_int)149 TEST_F(alu_srcs_negative_equal_test, trivial_int)
150 {
151    nir_def *two = nir_imm_int(&bld, 2);
152    nir_def *negative_two = nir_imm_int(&bld, -2);
153 
154    nir_def *result = nir_iadd(&bld, two, negative_two);
155    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);
156 
157    ASSERT_NE((void *) 0, instr);
158    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));
159    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 0));
160    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 1));
161 }
162 
TEST_F(alu_srcs_negative_equal_test,trivial_negation_float)163 TEST_F(alu_srcs_negative_equal_test, trivial_negation_float)
164 {
165    /* Cannot just do the negation of a nir_load_const_instr because
166     * nir_alu_srcs_negative_equal expects that constant folding will convert
167     * fneg(2.0) to just -2.0.
168     */
169    nir_def *two = nir_imm_float(&bld, 2.0f);
170    nir_def *two_plus_two = nir_fadd(&bld, two, two);
171    nir_def *negation = nir_fneg(&bld, two_plus_two);
172 
173    nir_def *result = nir_fadd(&bld, two_plus_two, negation);
174 
175    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);
176 
177    ASSERT_NE((void *) 0, instr);
178    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));
179    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 0));
180    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 1));
181 }
182 
TEST_F(alu_srcs_negative_equal_test,trivial_negation_int)183 TEST_F(alu_srcs_negative_equal_test, trivial_negation_int)
184 {
185    /* Cannot just do the negation of a nir_load_const_instr because
186     * nir_alu_srcs_negative_equal expects that constant folding will convert
187     * ineg(2) to just -2.
188     */
189    nir_def *two = nir_imm_int(&bld, 2);
190    nir_def *two_plus_two = nir_iadd(&bld, two, two);
191    nir_def *negation = nir_ineg(&bld, two_plus_two);
192 
193    nir_def *result = nir_iadd(&bld, two_plus_two, negation);
194 
195    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);
196 
197    ASSERT_NE((void *) 0, instr);
198    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));
199    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 0));
200    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 1));
201 }
202 
203 /* Compare an object with non-zero values to itself.  This should always be
204  * false.
205  */
206 #define compare_with_self(full_type)                                    \
207 TEST_F(alu_srcs_negative_equal_test, full_type ## _self)                \
208 {                                                                       \
209    count_sequence(c1, full_type, 1);                                    \
210    nir_def *a = nir_build_imm(&bld,                                 \
211                                   NIR_MAX_VEC_COMPONENTS,               \
212                                   nir_alu_type_get_type_size(full_type), \
213                                   c1);                                  \
214    nir_def *result;                                                 \
215    if (nir_alu_type_get_base_type(full_type) == nir_type_float)         \
216       result = nir_fadd(&bld, a, a);                                    \
217    else                                                                 \
218       result = nir_iadd(&bld, a, a);                                    \
219    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);       \
220    ASSERT_NE((void *) 0, instr);                                        \
221    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 0));       \
222    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));       \
223    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 0));       \
224    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 1));       \
225 }
226 
227 compare_with_self(nir_type_float16)
compare_with_self(nir_type_float32)228 compare_with_self(nir_type_float32)
229 compare_with_self(nir_type_float64)
230 compare_with_self(nir_type_int8)
231 compare_with_self(nir_type_uint8)
232 compare_with_self(nir_type_int16)
233 compare_with_self(nir_type_uint16)
234 compare_with_self(nir_type_int32)
235 compare_with_self(nir_type_uint32)
236 compare_with_self(nir_type_int64)
237 compare_with_self(nir_type_uint64)
238 
239 /* Compare an object with the negation of itself.  This should always be true.
240  */
241 #define compare_with_negation(full_type)                                \
242 TEST_F(alu_srcs_negative_equal_test, full_type ## _trivially_true)      \
243 {                                                                       \
244    count_sequence(c1, full_type, 1);                                    \
245    negate(c2, c1, full_type, NIR_MAX_VEC_COMPONENTS);                   \
246    nir_def *a = nir_build_imm(&bld,                                 \
247                                   NIR_MAX_VEC_COMPONENTS,               \
248                                   nir_alu_type_get_type_size(full_type), \
249                                   c1);                                  \
250    nir_def *b = nir_build_imm(&bld,                                 \
251                                   NIR_MAX_VEC_COMPONENTS,               \
252                                   nir_alu_type_get_type_size(full_type), \
253                                   c2);                                  \
254    nir_def *result;                                                 \
255    if (nir_alu_type_get_base_type(full_type) == nir_type_float)         \
256       result = nir_fadd(&bld, a, b);                                    \
257    else                                                                 \
258       result = nir_iadd(&bld, a, b);                                    \
259    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);       \
260    ASSERT_NE((void *) 0, instr);                                        \
261    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 0, 0));       \
262    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));        \
263    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 1, 0));        \
264    EXPECT_FALSE(nir_alu_srcs_negative_equal(instr, instr, 1, 1));       \
265 }
266 
267 compare_with_negation(nir_type_float16)
268 compare_with_negation(nir_type_float32)
269 compare_with_negation(nir_type_float64)
270 compare_with_negation(nir_type_int8)
271 compare_with_negation(nir_type_uint8)
272 compare_with_negation(nir_type_int16)
273 compare_with_negation(nir_type_uint16)
274 compare_with_negation(nir_type_int32)
275 compare_with_negation(nir_type_uint32)
276 compare_with_negation(nir_type_int64)
277 compare_with_negation(nir_type_uint64)
278 
279 TEST_F(alu_srcs_negative_equal_test, swizzle_scalar_to_vector)
280 {
281    nir_def *v = nir_imm_vec2(&bld, 1.0, -1.0);
282    const uint8_t s0[4] = { 0, 0, 0, 0 };
283    const uint8_t s1[4] = { 1, 1, 1, 1 };
284 
285    /* We can't use nir_swizzle here because it inserts an extra MOV. */
286    nir_alu_instr *instr = nir_alu_instr_create(bld.shader, nir_op_fadd);
287 
288    instr->src[0].src = nir_src_for_ssa(v);
289    instr->src[1].src = nir_src_for_ssa(v);
290 
291    memcpy(&instr->src[0].swizzle, s0, sizeof(s0));
292    memcpy(&instr->src[1].swizzle, s1, sizeof(s1));
293 
294    nir_builder_alu_instr_finish_and_insert(&bld, instr);
295 
296    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));
297 }
298 
299 static void
count_sequence(nir_const_value c[NIR_MAX_VEC_COMPONENTS],nir_alu_type full_type,int first)300 count_sequence(nir_const_value c[NIR_MAX_VEC_COMPONENTS],
301                nir_alu_type full_type, int first)
302 {
303    switch (full_type) {
304    case nir_type_float16:
305       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
306          c[i].u16 = _mesa_float_to_half(float(i + first));
307 
308       break;
309 
310    case nir_type_float32:
311       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
312          c[i].f32 = float(i + first);
313 
314       break;
315 
316    case nir_type_float64:
317       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
318          c[i].f64 = double(i + first);
319 
320       break;
321 
322    case nir_type_int8:
323    case nir_type_uint8:
324       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
325          c[i].i8 = i + first;
326 
327       break;
328 
329    case nir_type_int16:
330    case nir_type_uint16:
331       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
332          c[i].i16 = i + first;
333 
334       break;
335 
336    case nir_type_int32:
337    case nir_type_uint32:
338       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
339          c[i].i32 = i + first;
340 
341       break;
342 
343    case nir_type_int64:
344    case nir_type_uint64:
345       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
346          c[i].i64 = i + first;
347 
348       break;
349 
350    case nir_type_bool:
351    default:
352       unreachable("invalid base type");
353    }
354 }
355 
356 static void
negate(nir_const_value dst[NIR_MAX_VEC_COMPONENTS],const nir_const_value src[NIR_MAX_VEC_COMPONENTS],nir_alu_type full_type,unsigned components)357 negate(nir_const_value dst[NIR_MAX_VEC_COMPONENTS],
358        const nir_const_value src[NIR_MAX_VEC_COMPONENTS],
359        nir_alu_type full_type, unsigned components)
360 {
361    switch (full_type) {
362    case nir_type_float16:
363       for (unsigned i = 0; i < components; i++)
364          dst[i].u16 = _mesa_float_to_half(-_mesa_half_to_float(src[i].u16));
365 
366       break;
367 
368    case nir_type_float32:
369       for (unsigned i = 0; i < components; i++)
370          dst[i].f32 = -src[i].f32;
371 
372       break;
373 
374    case nir_type_float64:
375       for (unsigned i = 0; i < components; i++)
376          dst[i].f64 = -src[i].f64;
377 
378       break;
379 
380    case nir_type_int8:
381    case nir_type_uint8:
382       for (unsigned i = 0; i < components; i++)
383          dst[i].i8 = -src[i].i8;
384 
385       break;
386 
387    case nir_type_int16:
388    case nir_type_uint16:
389       for (unsigned i = 0; i < components; i++)
390          dst[i].i16 = -src[i].i16;
391 
392       break;
393 
394    case nir_type_int32:
395    case nir_type_uint32:
396       for (unsigned i = 0; i < components; i++)
397          dst[i].i32 = -src[i].i32;
398 
399       break;
400 
401    case nir_type_int64:
402    case nir_type_uint64:
403       for (unsigned i = 0; i < components; i++)
404          dst[i].i64 = -src[i].i64;
405 
406       break;
407 
408    case nir_type_bool:
409    default:
410       unreachable("invalid base type");
411    }
412 }
413