From aec0547838fa9d3d923a33755fb3aefe2dd81ba3 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 7 Jul 2020 17:30:42 -0700 Subject: [PATCH] nir/algebraic: Make some notes about comparison rearrangements versus infinity The original comment was a little terse and a little incorrect. The rearrangements are fine w.r.t. NaN. However, they produce incorrect results if one operand is +Inf and the other is -Inf. A later commit, "nir/algebraic: Add some compare-with-zero optimizations that are exact", will add some more patterns here. It may be reasonable to squash this commit (forward) into that commit. v2: Fix some incorrect comparisons operators in the comment (<= vs >=). Add commentary that subtraction works like addition w.r.t. NaN. Both noticed / suggested by Caio. Reviewed-by: Caio Marcelo de Oliveira Filho Part-of: --- src/compiler/nir/nir_opt_algebraic.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py index d7577c5..7dd1820 100644 --- a/src/compiler/nir/nir_opt_algebraic.py +++ b/src/compiler/nir/nir_opt_algebraic.py @@ -2053,8 +2053,27 @@ before_ffma_optimizations = [ # they help code generation but do not necessarily produce code that is # more easily optimizable. late_optimizations = [ - # Most of these optimizations aren't quite safe when you get infinity or - # Nan involved but the first one should be fine. + # The rearrangements are fine w.r.t. NaN. However, they produce incorrect + # results if one operand is +Inf and the other is -Inf. + # + # 1. Inf + -Inf = NaN + # 2. ∀x: x + NaN = NaN and x - NaN = NaN + # 3. ∀x: x != NaN = true + # 4. ∀x, ∀ cmp ∈ {<, >, ≤, ≥, =}: x cmp NaN = false + # + # a=Inf, b=-Inf a=-Inf, b=Inf a=NaN b=NaN + # (a+b) < 0 false false false false + # a < -b false false false false + # -(a+b) < 0 false false false false + # -a < b false false false false + # (a+b) >= 0 false false false false + # a >= -b true true false false + # -(a+b) >= 0 false false false false + # -a >= b true true false false + # (a+b) == 0 false false false false + # a == -b true true false false + # (a+b) != 0 true true true true + # a != -b false false true true (('flt', ('fadd', a, b), 0.0), ('flt', a, ('fneg', b))), (('flt', ('fneg', ('fadd', a, b)), 0.0), ('flt', ('fneg', a), b)), (('~fge', ('fadd', a, b), 0.0), ('fge', a, ('fneg', b))), -- 2.7.4