Module: Mesa Branch: master Commit: 55621c6d1c011e73c83ed3f95b1abc7f6ab9647e URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=55621c6d1c011e73c83ed3f95b1abc7f6ab9647e
Author: Ian Romanick <[email protected]> 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 <[email protected]> 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, \ _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
