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

Submitted by Eric Anholt on Feb. 7, 2015, 5:16 a.m.

Details

Message ID 1423286206-22967-3-git-send-email-eric@anholt.net
State New
Headers show

Not browsing as part of any series.

Commit Message

Eric Anholt Feb. 7, 2015, 5:16 a.m.
No change on shader-db on i965.
---
 src/glsl/nir/nir_opt_algebraic.py | 9 +++++++++
 1 file changed, 9 insertions(+)

Patch hide | download patch | download mbox

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.
+   (('ilt', a, a), False),
+   (('ige', a, a), True),
+   (('ieq', a, a), True),
+   (('ine', a, a), False),
+   (('ult', a, a), False),
+   (('uge', a, a), True),
    # Logical and bit operations
    (('fand', a, 0.0), 0.0),
    (('iand', a, a), a),

Comments

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>

On Sat, Feb 7, 2015 at 12:16 AM, Eric Anholt <eric@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.
> +   (('ilt', a, a), False),
> +   (('ige', a, a), True),
> +   (('ieq', a, a), True),
> +   (('ine', a, a), False),
> +   (('ult', a, a), False),
> +   (('uge', a, a), True),
>     # Logical and bit operations
>     (('fand', a, 0.0), 0.0),
>     (('iand', a, a), a),
> --
> 2.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
On Feb 6, 2015 9:16 PM, "Eric Anholt" <eric@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.
> +   (('ilt', a, a), False),
> +   (('ige', a, a), True),
> +   (('ieq', a, a), True),
> +   (('ine', a, a), False),
> +   (('ult', a, a), False),
> +   (('uge', a, a), True),
>     # Logical and bit operations
>     (('fand', a, 0.0), 0.0),
>     (('iand', a, a), a),
> --
> 2.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
On Sat, Feb 7, 2015 at 6:16 AM, Eric Anholt <eric@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.