Mesa (master): nir/algebraic: Add some compare-with-zero optimizations that are exact

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 5 02:24:37 UTC 2021


Module: Mesa
Branch: master
Commit: 55621c6d1c011e73c83ed3f95b1abc7f6ab9647e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=55621c6d1c011e73c83ed3f95b1abc7f6ab9647e

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Mon Aug 10 18:34:37 2020 -0700

nir/algebraic: Add some compare-with-zero optimizations that are exact

This prevents some fossil-db regressions in "spir-v: Mark floating point
comparisons exact".

v2: Note that the patterns and replacements produce the same value when
isnan(b).  Suggested by Caio.

v3: Use C99 isfinite() instead of (obsolete) BSD finite().  Fixes
various Windows builds.

No fossil-db changes on any Inetl platform, Vega, or Polaris10.

All Intel platforms had similar results. (Tiger Lake shown)
total instructions in shared programs: 20908670 -> 20908672 (<.01%)
instructions in affected programs: 69 -> 71 (2.90%)
helped: 0
HURT: 1

total cycles in shared programs: 473515288 -> 473513940 (<.01%)
cycles in affected programs: 4942 -> 3594 (-27.28%)
helped: 2
HURT: 0

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6358>

---

 src/compiler/nir/nir_opt_algebraic.py |  8 ++++++++
 src/compiler/nir/nir_search_helpers.h | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py
index 7401047563f..11b54bf2555 100644
--- a/src/compiler/nir/nir_opt_algebraic.py
+++ b/src/compiler/nir/nir_opt_algebraic.py
@@ -2079,6 +2079,14 @@ late_optimizations = [
    (('~feq', ('fadd', a, b), 0.0), ('feq', a, ('fneg', b))),
    (('~fneu', ('fadd', a, b), 0.0), ('fneu', a, ('fneg', b))),
 
+   # If either source must be finite, then the original (a+b) cannot produce
+   # NaN due to Inf-Inf.  The patterns and the replacements produce the same
+   # result if b is NaN. Therefore, the replacements are exact.
+   (('fge',          ('fadd', 'a(is_finite)', b),  0.0), ('fge',          a, ('fneg', b))),
+   (('fge', ('fneg', ('fadd', 'a(is_finite)', b)), 0.0), ('fge', ('fneg', a),         b)),
+   (('feq',  ('fadd', 'a(is_finite)', b), 0.0), ('feq',  a, ('fneg', b))),
+   (('fneu', ('fadd', 'a(is_finite)', b), 0.0), ('fneu', a, ('fneg', b))),
+
    # nir_lower_to_source_mods will collapse this, but its existence during the
    # optimization loop can prevent other optimizations.
    (('fneg', ('fneg', a)), a),
diff --git a/src/compiler/nir/nir_search_helpers.h b/src/compiler/nir/nir_search_helpers.h
index ef3e6526682..4ef9b49c30c 100644
--- a/src/compiler/nir/nir_search_helpers.h
+++ b/src/compiler/nir/nir_search_helpers.h
@@ -387,6 +387,40 @@ is_integral(struct hash_table *ht, nir_alu_instr *instr, unsigned src,
    return r.is_integral;
 }
 
+/**
+ * Is the value finite?
+ *
+ * Doesn't actually use range tracking.  Just checks that the value is a
+ * constant that is finite.
+ */
+static inline bool
+is_finite(UNUSED struct hash_table *ht, nir_alu_instr *instr, unsigned src,
+          unsigned num_components, const uint8_t *swizzle)
+{
+   if (nir_src_as_const_value(instr->src[src].src) == NULL)
+      return false;
+
+   for (unsigned i = 0; i < num_components; i++) {
+      nir_alu_type type = nir_op_infos[instr->op].input_types[src];
+      switch (nir_alu_type_get_base_type(type)) {
+      case nir_type_float:
+         if (!isfinite(nir_src_comp_as_float(instr->src[src].src, swizzle[i])))
+            return false;
+         break;
+      case nir_type_bool:
+      case nir_type_int:
+      case nir_type_uint:
+         /* Non-float types are always finite. */
+         break;
+      default:
+         return false;
+      }
+   }
+
+   return true;
+}
+
+
 #define RELATION(r)                                                     \
 static inline bool                                                      \
 is_ ## r (struct hash_table *ht, nir_alu_instr *instr, unsigned src,                           \



More information about the mesa-commit mailing list