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