[Mesa-dev] [PATCH 3/3] nir: Add algebraic optimizations for comparisons with identical operands.

Erik Faye-Lund kusmabite at gmail.com
Sat Feb 7 05:24:31 PST 2015


On Sat, Feb 7, 2015 at 6:16 AM, Eric Anholt <eric at anholt.net> wrote:
> No change on shader-db on i965.
> ---
>  src/glsl/nir/nir_opt_algebraic.py | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/src/glsl/nir/nir_opt_algebraic.py b/src/glsl/nir/nir_opt_algebraic.py
> index a5fe19a..0512a8f 100644
> --- a/src/glsl/nir/nir_opt_algebraic.py
> +++ b/src/glsl/nir/nir_opt_algebraic.py
> @@ -83,6 +83,15 @@ optimizations = [
>     (('fne', ('fadd', a, b), 0.0), ('fne', a, ('fneg', b))),
>     (('fge', ('fneg', ('fabs', a)), 0.0), ('feq', a, 0.0)),
>     (('fmin', ('fmax', a, 0.0), 1.0), ('fsat', a)),
> +   # Comparison with the same args.  Note that these are not done for
> +   # the float versions because float equality is used to test for
> +   # NaN.

I think this comment is a bit odd, as it kind of describes the wrong
part of the story (although it helps you to get in the right
direction).

The issue isn't that float equality is used to test for NaN, but that
IEEE 754 defines any equality-comparison with NaN to evaluate to
false. And that's the reason why you *can* use float equality to check
for NaN.

This also means that we can still do 'lt' and 'gt' safely for floats.
In fact, GCC does these optimizations:

---8<---
int eq(float a) { return a == a; }
int neq(float a) { return a != a; }
int lt(float a) { return a < a; }
int lte(float a) { return a <= a; }
int gt(float a) { return a > a; }
int gte(float a) { return a >= a; }
---8<---

If you compile that program (even with optimizations disabled), GCC
will make lt and gt simply return 0.


More information about the mesa-dev mailing list