[Mesa-dev] [PATCH 6/9] nir: Add nir_const_value_negative_equal

Thomas Helland thomashelland90 at gmail.com
Mon Oct 8 20:56:06 UTC 2018


I really like this one; its very readable =)

Reviewed-by: Thomas Helland<thomashelland90 at gmail.com>

Den tor. 30. aug. 2018 kl. 07:37 skrev Ian Romanick <idr at freedesktop.org>:
>
> From: Ian Romanick <ian.d.romanick at intel.com>
>
> Signed-off-by: Ian Romanick <ian.d.romanick at 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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list