From: Ian Romanick <ian.d.roman...@intel.com> Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> --- src/compiler/nir/meson.build | 12 + src/compiler/nir/nir.h | 6 + src/compiler/nir/nir_instr_set.c | 98 +++++++++ src/compiler/nir/tests/negative_equal_tests.cpp | 278 ++++++++++++++++++++++++ 4 files changed, 394 insertions(+) create mode 100644 src/compiler/nir/tests/negative_equal_tests.cpp
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build index 090aa7a628f..5438c17a8f8 100644 --- a/src/compiler/nir/meson.build +++ b/src/compiler/nir/meson.build @@ -245,4 +245,16 @@ if with_tests link_with : libmesa_util, ) ) + + test( + 'negative_equal', + executable( + 'negative_equal', + files('tests/negative_equal_tests.cpp'), + c_args : [c_vis_args, c_msvc_compat_args, no_override_init_args], + include_directories : [inc_common], + dependencies : [dep_thread, idep_gtest, idep_nir], + link_with : libmesa_util, + ) + ) endif diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 9bca6d487e9..f94538e0782 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -955,6 +955,12 @@ nir_ssa_alu_instr_src_components(const nir_alu_instr *instr, unsigned src) return instr->dest.dest.ssa.num_components; } +bool nir_const_value_negative_equal(const nir_const_value *c1, + const nir_const_value *c2, + unsigned components, + nir_alu_type base_type, + unsigned bits); + bool nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2, unsigned src1, unsigned src2); diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c index 19771fcd9dd..009d9661e60 100644 --- a/src/compiler/nir/nir_instr_set.c +++ b/src/compiler/nir/nir_instr_set.c @@ -23,6 +23,7 @@ #include "nir_instr_set.h" #include "nir_vla.h" +#include "util/half_float.h" #define HASH(hash, data) _mesa_fnv32_1a_accumulate((hash), (data)) @@ -261,6 +262,103 @@ nir_srcs_equal(nir_src src1, nir_src src2) } } +bool +nir_const_value_negative_equal(const nir_const_value *c1, + const nir_const_value *c2, + unsigned components, + nir_alu_type base_type, + unsigned bits) +{ + assert(base_type == nir_alu_type_get_base_type(base_type)); + assert(base_type != nir_type_invalid); + + switch (base_type) { + case nir_type_float: + switch (bits) { + case 16: + for (unsigned i = 0; i < components; i++) { + if (_mesa_half_to_float(c1->u16[i]) != + -_mesa_half_to_float(c2->u16[i])) { + return false; + } + } + + return true; + + case 32: + for (unsigned i = 0; i < components; i++) { + if (c1->f32[i] != -c2->f32[i]) + return false; + } + + return true; + + case 64: + for (unsigned i = 0; i < components; i++) { + if (c1->f64[i] != -c2->f64[i]) + return false; + } + + return true; + + default: + unreachable("unknown bit size"); + } + + break; + + case nir_type_int: + case nir_type_uint: + switch (bits) { + case 8: + for (unsigned i = 0; i < components; i++) { + if (c1->i8[i] != -c2->i8[i]) + return false; + } + + return true; + + case 16: + for (unsigned i = 0; i < components; i++) { + if (c1->i16[i] != -c2->i16[i]) + return false; + } + + return true; + break; + + case 32: + for (unsigned i = 0; i < components; i++) { + if (c1->i32[i] != -c2->i32[i]) + return false; + } + + return true; + + case 64: + for (unsigned i = 0; i < components; i++) { + if (c1->i64[i] != -c2->i64[i]) + return false; + } + + return true; + + default: + unreachable("unknown bit size"); + } + + break; + + case nir_type_bool: + return false; + + default: + break; + } + + return false; +} + bool nir_alu_srcs_equal(const nir_alu_instr *alu1, const nir_alu_instr *alu2, unsigned src1, unsigned src2) diff --git a/src/compiler/nir/tests/negative_equal_tests.cpp b/src/compiler/nir/tests/negative_equal_tests.cpp new file mode 100644 index 00000000000..e450a8172db --- /dev/null +++ b/src/compiler/nir/tests/negative_equal_tests.cpp @@ -0,0 +1,278 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <gtest/gtest.h> +#include "nir.h" +#include "util/half_float.h" + +static nir_const_value count_sequence(nir_alu_type base_type, unsigned bits, + int first); +static nir_const_value negate(const nir_const_value &src, + nir_alu_type base_type, unsigned bits, + unsigned components); + +class const_value_negative_equal_test : public ::testing::Test { +protected: + const_value_negative_equal_test() + { + memset(&c1, 0, sizeof(c1)); + memset(&c2, 0, sizeof(c2)); + } + + ~const_value_negative_equal_test() + { + /* empty */ + } + + nir_const_value c1; + nir_const_value c2; +}; + + +TEST_F(const_value_negative_equal_test, float32_zero) +{ + /* Verify that 0.0 negative-equals 0.0. */ + EXPECT_TRUE(nir_const_value_negative_equal(&c1, &c1, + 4, nir_type_float, 32)); +} + +TEST_F(const_value_negative_equal_test, float64_zero) +{ + /* Verify that 0.0 negative-equals 0.0. */ + EXPECT_TRUE(nir_const_value_negative_equal(&c1, &c1, + 4, nir_type_float, 64)); +} + +/* Compare an object with non-zero values to itself. This should always be + * false. + */ +#define compare_with_self(base_type, bits) \ +TEST_F(const_value_negative_equal_test, base_type ## bits ## _self) \ +{ \ + c1 = count_sequence(base_type, bits, 1); \ + EXPECT_FALSE(nir_const_value_negative_equal(&c1, &c1, 4, base_type, bits)); \ +} + +compare_with_self(nir_type_float, 16) +compare_with_self(nir_type_float, 32) +compare_with_self(nir_type_float, 64) +compare_with_self(nir_type_int, 8) +compare_with_self(nir_type_uint, 8) +compare_with_self(nir_type_int, 16) +compare_with_self(nir_type_uint, 16) +compare_with_self(nir_type_int, 32) +compare_with_self(nir_type_uint, 32) +compare_with_self(nir_type_int, 64) +compare_with_self(nir_type_uint, 64) + +/* Compare an object with the negation of itself. This should always be true. + */ +#define compare_with_negation(base_type, bits) \ +TEST_F(const_value_negative_equal_test, base_type ## bits ## _trivially_true) \ +{ \ + c1 = count_sequence(base_type, bits, 1); \ + c2 = negate(c1, base_type, bits, 4); \ + EXPECT_TRUE(nir_const_value_negative_equal(&c1, &c2, 4, base_type, bits)); \ +} + +compare_with_negation(nir_type_float, 16) +compare_with_negation(nir_type_float, 32) +compare_with_negation(nir_type_float, 64) +compare_with_negation(nir_type_int, 8) +compare_with_negation(nir_type_uint, 8) +compare_with_negation(nir_type_int, 16) +compare_with_negation(nir_type_uint, 16) +compare_with_negation(nir_type_int, 32) +compare_with_negation(nir_type_uint, 32) +compare_with_negation(nir_type_int, 64) +compare_with_negation(nir_type_uint, 64) + +/* Compare fewer than the maximum possible components. All of the components + * that are compared a negative-equal, but the extra components are not. + */ +#define compare_fewer_components(base_type, bits) \ +TEST_F(const_value_negative_equal_test, base_type ## bits ## _fewer_components) \ +{ \ + c1 = count_sequence(base_type, bits, 1); \ + c2 = negate(c1, base_type, bits, 3); \ + EXPECT_TRUE(nir_const_value_negative_equal(&c1, &c2, 3, base_type, bits)); \ + EXPECT_FALSE(nir_const_value_negative_equal(&c1, &c2, 4, base_type, bits)); \ +} + +compare_fewer_components(nir_type_float, 16) +compare_fewer_components(nir_type_float, 32) +compare_fewer_components(nir_type_float, 64) +compare_fewer_components(nir_type_int, 8) +compare_fewer_components(nir_type_uint, 8) +compare_fewer_components(nir_type_int, 16) +compare_fewer_components(nir_type_uint, 16) +compare_fewer_components(nir_type_int, 32) +compare_fewer_components(nir_type_uint, 32) +compare_fewer_components(nir_type_int, 64) +compare_fewer_components(nir_type_uint, 64) + +static nir_const_value +count_sequence(nir_alu_type base_type, unsigned bits, int first) +{ + nir_const_value c; + + switch (base_type) { + case nir_type_float: + switch (bits) { + case 16: + for (unsigned i = 0; i < ARRAY_SIZE(c.u16); i++) + c.u16[i] = _mesa_float_to_half(float(i + first)); + + break; + + case 32: + for (unsigned i = 0; i < ARRAY_SIZE(c.f32); i++) + c.f32[i] = float(i + first); + + break; + + case 64: + for (unsigned i = 0; i < ARRAY_SIZE(c.f64); i++) + c.f64[i] = double(i + first); + + break; + + default: + unreachable("unknown bit size"); + } + + break; + + case nir_type_int: + case nir_type_uint: + switch (bits) { + case 8: + for (unsigned i = 0; i < ARRAY_SIZE(c.i8); i++) + c.i8[i] = i + first; + + break; + + case 16: + for (unsigned i = 0; i < ARRAY_SIZE(c.i16); i++) + c.i16[i] = i + first; + + break; + + case 32: + for (unsigned i = 0; i < ARRAY_SIZE(c.i32); i++) + c.i32[i] = i + first; + + break; + + case 64: + for (unsigned i = 0; i < ARRAY_SIZE(c.i64); i++) + c.i64[i] = i + first; + + break; + + default: + unreachable("unknown bit size"); + } + + break; + + case nir_type_bool: + default: + unreachable("invalid base type"); + } + + return c; +} + +static nir_const_value +negate(const nir_const_value &src, nir_alu_type base_type, unsigned bits, + unsigned components) +{ + nir_const_value c = src; + + switch (base_type) { + case nir_type_float: + switch (bits) { + case 16: + for (unsigned i = 0; i < components; i++) + c.u16[i] = _mesa_float_to_half(-_mesa_half_to_float(c.u16[i])); + + break; + + case 32: + for (unsigned i = 0; i < components; i++) + c.f32[i] = -c.f32[i]; + + break; + + case 64: + for (unsigned i = 0; i < components; i++) + c.f64[i] = -c.f64[i]; + + break; + + default: + unreachable("unknown bit size"); + } + + break; + + case nir_type_int: + case nir_type_uint: + switch (bits) { + case 8: + for (unsigned i = 0; i < components; i++) + c.i8[i] = -c.i8[i]; + + break; + + case 16: + for (unsigned i = 0; i < components; i++) + c.i16[i] = -c.i16[i]; + + break; + + case 32: + for (unsigned i = 0; i < components; i++) + c.i32[i] = -c.i32[i]; + + break; + + case 64: + for (unsigned i = 0; i < components; i++) + c.i64[i] = -c.i64[i]; + + break; + + default: + unreachable("unknown bit size"); + } + + break; + + case nir_type_bool: + default: + unreachable("invalid base type"); + } + + return c; +} -- 2.14.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev