[Mesa-dev] [PATCH] nir/algebraic: Add optimizations for "a == a && a CMP b"

Ian Romanick idr at freedesktop.org
Thu Dec 22 21:37:12 UTC 2016

```On 12/22/2016 01:14 PM, Jason Ekstrand wrote:
> On Thu, Dec 22, 2016 at 1:13 PM, Ian Romanick <idr at freedesktop.org
> <mailto:idr at freedesktop.org>> wrote:
>
>     On 12/19/2016 09:32 PM, Jason Ekstrand wrote:
>     > This sequence shows up The Talos Principal, at least under Vulkan,
>     > and prevents loop analysis from properly computing trip counts in a
>     > few loops.
>     > ---
>     >  src/compiler/nir/nir_opt_algebraic.py | 8 ++++++++
>     >  1 file changed, 8 insertions(+)
>     >
>     > diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py
>     > index 698ac67..cc70ad5 100644
>     > --- a/src/compiler/nir/nir_opt_algebraic.py
>     > +++ b/src/compiler/nir/nir_opt_algebraic.py
>     > @@ -464,6 +464,14 @@ def bitfield_reverse(u):
>     >
>     >  optimizations += [(bitfield_reverse('x at 32'), ('bitfield_reverse', 'x'))]
>     >
>     > +# For any comparison operation, "cmp", if you have "a != a && a cmp b" then
>     > +# the "a != a" is redundant because it's equivalent to "a is not NaN" and, if
>     > +# a is a NaN then the second comparison will fail anyway.
>     > +for op in ['flt', 'fge', 'feq', 'fne']:
>     > +   optimizations += [
>     > +      (('iand', ('feq', a, a), (op, a, b)), (op, a, b)),
>     > +      (('iand', ('feq', a, a), (op, b, a)), (op, b, a)),
>     > +   ]
>
>     I don't think this is right.  That will change (NaN == NaN) && (NaN !=
>     7) from false to true.  Right?  You should just drop fne from the
>     list... I think.  Math is hard.
>
> Don't all comparisons with NaN return false?  Wouldn't NaN != 7 be
> false?  Maybe I don't understand NaN!

As far as I'm aware, (!(a == b)) is always the same as (a !== b).
According to
https://en.wikipedia.org/wiki/IEEE_754-1985#Recommended_functions_and_predicates,
a != a is how you can implement isnan().

> --Jason
>
>     >  # Add optimizations to handle the case where the result of a
>     ternary is
>     >  # compared to a constant.  This way we can take things like

```