• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ssa_def *two = nir_imm_float(&bld, 2.0f);
138    nir_ssa_def *negative_two = nir_imm_float(&bld, -2.0f);
139 
140    nir_ssa_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_ssa_def *two = nir_imm_int(&bld, 2);
152    nir_ssa_def *negative_two = nir_imm_int(&bld, -2);
153 
154    nir_ssa_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_ssa_def *two = nir_imm_float(&bld, 2.0f);
170    nir_ssa_def *two_plus_two = nir_fadd(&bld, two, two);
171    nir_ssa_def *negation = nir_fneg(&bld, two_plus_two);
172 
173    nir_ssa_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_ssa_def *two = nir_imm_int(&bld, 2);
190    nir_ssa_def *two_plus_two = nir_iadd(&bld, two, two);
191    nir_ssa_def *negation = nir_ineg(&bld, two_plus_two);
192 
193    nir_ssa_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_ssa_def *a = nir_build_imm(&bld,                                 \
211                                   NIR_MAX_VEC_COMPONENTS,               \
212                                   nir_alu_type_get_type_size(full_type), \
213                                   c1);                                  \
214    nir_ssa_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_ssa_def *a = nir_build_imm(&bld,                                 \
247                                   NIR_MAX_VEC_COMPONENTS,               \
248                                   nir_alu_type_get_type_size(full_type), \
249                                   c1);                                  \
250    nir_ssa_def *b = nir_build_imm(&bld,                                 \
251                                   NIR_MAX_VEC_COMPONENTS,               \
252                                   nir_alu_type_get_type_size(full_type), \
253                                   c2);                                  \
254    nir_ssa_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_ssa_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 
TEST_F(alu_srcs_negative_equal_test,unused_components_mismatch)299 TEST_F(alu_srcs_negative_equal_test, unused_components_mismatch)
300 {
301    nir_ssa_def *v1 = nir_imm_vec4(&bld, -2.0, 18.0, 43.0,  1.0);
302    nir_ssa_def *v2 = nir_imm_vec4(&bld,  2.0, 99.0, 76.0, -1.0);
303 
304    nir_ssa_def *result = nir_fadd(&bld, v1, v2);
305 
306    nir_alu_instr *instr = nir_instr_as_alu(result->parent_instr);
307 
308    /* Disable the channels that aren't negations of each other. */
309    nir_register *reg = nir_local_reg_create(bld.impl);
310    nir_instr_rewrite_dest(&instr->instr, &instr->dest.dest, nir_dest_for_reg(reg));
311    instr->dest.write_mask = 8 + 1;
312 
313    EXPECT_TRUE(nir_alu_srcs_negative_equal(instr, instr, 0, 1));
314 }
315 
316 static void
count_sequence(nir_const_value c[NIR_MAX_VEC_COMPONENTS],nir_alu_type full_type,int first)317 count_sequence(nir_const_value c[NIR_MAX_VEC_COMPONENTS],
318                nir_alu_type full_type, int first)
319 {
320    switch (full_type) {
321    case nir_type_float16:
322       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
323          c[i].u16 = _mesa_float_to_half(float(i + first));
324 
325       break;
326 
327    case nir_type_float32:
328       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
329          c[i].f32 = float(i + first);
330 
331       break;
332 
333    case nir_type_float64:
334       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
335          c[i].f64 = double(i + first);
336 
337       break;
338 
339    case nir_type_int8:
340    case nir_type_uint8:
341       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
342          c[i].i8 = i + first;
343 
344       break;
345 
346    case nir_type_int16:
347    case nir_type_uint16:
348       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
349          c[i].i16 = i + first;
350 
351       break;
352 
353    case nir_type_int32:
354    case nir_type_uint32:
355       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
356          c[i].i32 = i + first;
357 
358       break;
359 
360    case nir_type_int64:
361    case nir_type_uint64:
362       for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
363          c[i].i64 = i + first;
364 
365       break;
366 
367    case nir_type_bool:
368    default:
369       unreachable("invalid base type");
370    }
371 }
372 
373 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)374 negate(nir_const_value dst[NIR_MAX_VEC_COMPONENTS],
375        const nir_const_value src[NIR_MAX_VEC_COMPONENTS],
376        nir_alu_type full_type, unsigned components)
377 {
378    switch (full_type) {
379    case nir_type_float16:
380       for (unsigned i = 0; i < components; i++)
381          dst[i].u16 = _mesa_float_to_half(-_mesa_half_to_float(src[i].u16));
382 
383       break;
384 
385    case nir_type_float32:
386       for (unsigned i = 0; i < components; i++)
387          dst[i].f32 = -src[i].f32;
388 
389       break;
390 
391    case nir_type_float64:
392       for (unsigned i = 0; i < components; i++)
393          dst[i].f64 = -src[i].f64;
394 
395       break;
396 
397    case nir_type_int8:
398    case nir_type_uint8:
399       for (unsigned i = 0; i < components; i++)
400          dst[i].i8 = -src[i].i8;
401 
402       break;
403 
404    case nir_type_int16:
405    case nir_type_uint16:
406       for (unsigned i = 0; i < components; i++)
407          dst[i].i16 = -src[i].i16;
408 
409       break;
410 
411    case nir_type_int32:
412    case nir_type_uint32:
413       for (unsigned i = 0; i < components; i++)
414          dst[i].i32 = -src[i].i32;
415 
416       break;
417 
418    case nir_type_int64:
419    case nir_type_uint64:
420       for (unsigned i = 0; i < components; i++)
421          dst[i].i64 = -src[i].i64;
422 
423       break;
424 
425    case nir_type_bool:
426    default:
427       unreachable("invalid base type");
428    }
429 }
430