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