2 * Copyright © 2018 Intel Corporation
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:
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
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.
23 #include <gtest/gtest.h>
25 #include "nir_builder.h"
26 #include "util/half_float.h"
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
);
34 class const_value_negative_equal_test
: public ::testing::Test
{
36 const_value_negative_equal_test()
38 glsl_type_singleton_init_or_ref();
40 memset(c1
, 0, sizeof(c1
));
41 memset(c2
, 0, sizeof(c2
));
44 ~const_value_negative_equal_test()
46 glsl_type_singleton_decref();
49 nir_const_value c1
[NIR_MAX_VEC_COMPONENTS
];
50 nir_const_value c2
[NIR_MAX_VEC_COMPONENTS
];
53 class alu_srcs_negative_equal_test
: public ::testing::Test
{
55 alu_srcs_negative_equal_test()
57 glsl_type_singleton_init_or_ref();
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
));
65 ~alu_srcs_negative_equal_test()
67 ralloc_free(bld
.shader
);
68 glsl_type_singleton_decref();
71 struct nir_builder bld
;
72 nir_const_value c1
[NIR_MAX_VEC_COMPONENTS
];
73 nir_const_value c2
[NIR_MAX_VEC_COMPONENTS
];
76 TEST_F(const_value_negative_equal_test
, float32_zero
)
78 /* Verify that 0.0 negative-equals 0.0. */
79 EXPECT_TRUE(nir_const_value_negative_equal(c1
[0], c1
[0], nir_type_float32
));
82 TEST_F(const_value_negative_equal_test
, float64_zero
)
84 /* Verify that 0.0 negative-equals 0.0. */
85 EXPECT_TRUE(nir_const_value_negative_equal(c1
[0], c1
[0], nir_type_float64
));
88 /* Compare an object with non-zero values to itself. This should always be
91 #define compare_with_self(full_type) \
92 TEST_F(const_value_negative_equal_test, full_type ## _self) \
94 count_sequence(c1, full_type, 1); \
95 EXPECT_FALSE(nir_const_value_negative_equal(c1[0], c1[0], full_type)); \
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
111 /* Compare an object with the negation of itself. This should always be true.
113 #define compare_with_negation(full_type) \
114 TEST_F(const_value_negative_equal_test, full_type ## _trivially_true) \
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)); \
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
134 TEST_F(alu_srcs_negative_equal_test
, trivial_float
)
136 nir_ssa_def
*two
= nir_imm_float(&bld
, 2.0f
);
137 nir_ssa_def
*negative_two
= nir_imm_float(&bld
, -2.0f
);
139 nir_ssa_def
*result
= nir_fadd(&bld
, two
, negative_two
);
140 nir_alu_instr
*instr
= nir_instr_as_alu(result
->parent_instr
);
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));
148 TEST_F(alu_srcs_negative_equal_test
, trivial_int
)
150 nir_ssa_def
*two
= nir_imm_int(&bld
, 2);
151 nir_ssa_def
*negative_two
= nir_imm_int(&bld
, -2);
153 nir_ssa_def
*result
= nir_iadd(&bld
, two
, negative_two
);
154 nir_alu_instr
*instr
= nir_instr_as_alu(result
->parent_instr
);
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));
162 TEST_F(alu_srcs_negative_equal_test
, trivial_negation_float
)
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.
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
);
172 nir_ssa_def
*result
= nir_fadd(&bld
, two_plus_two
, negation
);
174 nir_alu_instr
*instr
= nir_instr_as_alu(result
->parent_instr
);
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));
182 TEST_F(alu_srcs_negative_equal_test
, trivial_negation_int
)
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.
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
);
192 nir_ssa_def
*result
= nir_iadd(&bld
, two_plus_two
, negation
);
194 nir_alu_instr
*instr
= nir_instr_as_alu(result
->parent_instr
);
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));
202 /* Compare an object with non-zero values to itself. This should always be
205 #define compare_with_self(full_type) \
206 TEST_F(alu_srcs_negative_equal_test, full_type ## _self) \
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), \
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); \
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)); \
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
)
238 /* Compare an object with the negation of itself. This should always be true.
240 #define compare_with_negation(full_type) \
241 TEST_F(alu_srcs_negative_equal_test, full_type ## _trivially_true) \
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), \
249 nir_ssa_def *b = nir_build_imm(&bld, \
250 NIR_MAX_VEC_COMPONENTS, \
251 nir_alu_type_get_type_size(full_type), \
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); \
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)); \
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
)
278 TEST_F(alu_srcs_negative_equal_test
, swizzle_scalar_to_vector
)
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 };
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
);
287 instr
->src
[0].src
= nir_src_for_ssa(v
);
288 instr
->src
[1].src
= nir_src_for_ssa(v
);
290 memcpy(&instr
->src
[0].swizzle
, s0
, sizeof(s0
));
291 memcpy(&instr
->src
[1].swizzle
, s1
, sizeof(s1
));
293 nir_builder_alu_instr_finish_and_insert(&bld
, instr
);
295 EXPECT_TRUE(nir_alu_srcs_negative_equal(instr
, instr
, 0, 1));
298 TEST_F(alu_srcs_negative_equal_test
, unused_components_mismatch
)
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);
303 nir_ssa_def
*result
= nir_fadd(&bld
, v1
, v2
);
305 nir_alu_instr
*instr
= nir_instr_as_alu(result
->parent_instr
);
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;
311 EXPECT_TRUE(nir_alu_srcs_negative_equal(instr
, instr
, 0, 1));
315 count_sequence(nir_const_value c
[NIR_MAX_VEC_COMPONENTS
],
316 nir_alu_type full_type
, int first
)
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
));
325 case nir_type_float32
:
326 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++)
327 c
[i
].f32
= float(i
+ first
);
331 case nir_type_float64
:
332 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++)
333 c
[i
].f64
= double(i
+ first
);
339 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++)
345 case nir_type_uint16
:
346 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++)
347 c
[i
].i16
= i
+ first
;
352 case nir_type_uint32
:
353 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++)
354 c
[i
].i32
= i
+ first
;
359 case nir_type_uint64
:
360 for (unsigned i
= 0; i
< NIR_MAX_VEC_COMPONENTS
; i
++)
361 c
[i
].i64
= i
+ first
;
367 unreachable("invalid base type");
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
)
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
));
383 case nir_type_float32
:
384 for (unsigned i
= 0; i
< components
; i
++)
385 dst
[i
].f32
= -src
[i
].f32
;
389 case nir_type_float64
:
390 for (unsigned i
= 0; i
< components
; i
++)
391 dst
[i
].f64
= -src
[i
].f64
;
397 for (unsigned i
= 0; i
< components
; i
++)
398 dst
[i
].i8
= -src
[i
].i8
;
403 case nir_type_uint16
:
404 for (unsigned i
= 0; i
< components
; i
++)
405 dst
[i
].i16
= -src
[i
].i16
;
410 case nir_type_uint32
:
411 for (unsigned i
= 0; i
< components
; i
++)
412 dst
[i
].i32
= -src
[i
].i32
;
417 case nir_type_uint64
:
418 for (unsigned i
= 0; i
< components
; i
++)
419 dst
[i
].i64
= -src
[i
].i64
;
425 unreachable("invalid base type");