nir: Use b2b opcodes for shared and constant memory
[mesa.git] / src / compiler / nir / tests / negative_equal_tests.cpp
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:
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
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:
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
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
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
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)
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
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
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
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)
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
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
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
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 }