nir/algebraic: Fix NaN-unsafe fcsel patterns
authorIan Romanick <ian.d.romanick@intel.com>
Thu, 25 Mar 2021 20:13:21 +0000 (13:13 -0700)
committerMarge Bot <emma+marge@anholt.net>
Wed, 22 Jun 2022 19:26:59 +0000 (19:26 +0000)
commita2a2fbc5101d6e6b5d18903c7a0bd84037dbdddc
tree3f58db52b7369b0090ad488d6b3c7a6dfef6db8f
parentccd18ec4f34b6f1407fb7c1671de8c789f33fa1f
nir/algebraic: Fix NaN-unsafe fcsel patterns

For example, the proof for this pattern

    (('bcsel', ('flt', 'a@32', 0), 'b@32', 'c@32'), ('fcsel_ge', a, c, b)),

would be

    bcsel(a < 0, b, c)
    bcsel(!(a < 0), c, b)
    bcsel(a >= 0, c, b)
    fcsel_ge(a, c, b)

However, !(a < 0) => (a >= 0) is well known to produce different
results if `a` is NaN.

Instead of that replacement, use this replacement:

    bcsel(a < 0, b, c)
    bcsel(-0 < -a, b, c)
    bcsel(0 < -a, b, c)
    fcsel_gt(-a, b, c)

This is NaN-safe and exact.

Reviewed-by: Alyssa Rosenzweig <alyssa@collabora.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Fixes: 0f5b3c37c5d ("nir: Add opcodes for fused comp + csel and optimizations")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17048>
src/compiler/nir/nir_opt_algebraic.py