public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Ignore (possible) signed zeros in operands of FP comparisons.
@ 2022-03-14 19:25 Roger Sayle
  2022-03-15  7:29 ` Richard Biener
  0 siblings, 1 reply; 15+ messages in thread
From: Roger Sayle @ 2022-03-14 19:25 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1599 bytes --]


I've been wondering about the possible performance/missed-optimization
impact of my patch for PR middle-end/98420 and similar IEEE correctness
fixes that disable constant folding optimizations when worrying about -0.0.
In the common situation where the floating point result is used by a
FP comparison, there's no distinction between +0.0 and -0.0, so some
HONOR_SIGNED_ZEROS optimizations that we'd usually disable, are safe.

Consider the following interesting example:

int foo(int x, double y) {
    return (x * 0.0) < y;
}

Although we know that x (when converted to double) can't be NaN or Inf,
we still worry that for negative values of x that (x * 0.0) may be -0.0
and so perform the multiplication at run-time.  But in this case, the
result of the comparison (-0.0 < y) will be exactly the same as (+0.0 < y)
for any y, hence the above may be safely constant folded to "0.0 < y"
avoiding the multiplication at run-time.

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check with no new failures, and allows GCC to continue to
optimize cases that we optimized in GCC 11 (without regard to correctness).
Ok for mainline?


2022-03-14  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
	* match.pd (X CMP (Y-Y) -> X CMP 0.0): New transformation.
	(X CMP (Y * 0.0) -> X CMP 0.0): Likewise.
	(X CMP X -> true): Test tree_expr_maybe_nan_p instead of HONOR_NANS.
	(X LTGT X -> false): Enable if X is not tree_expr_maybe_nan_p, as
	this can't trap/signal.

gcc/testsuite/ChangeLog
	* gcc.dg/fold-compare-9.c: New test case.


Thanks in advance,
Roger
--


[-- Attachment #2: patchrm3.txt --]
[-- Type: text/plain, Size: 2725 bytes --]

diff --git a/gcc/match.pd b/gcc/match.pd
index 8b44b5c..f3f7865 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4671,6 +4671,35 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (if (single_use (@2))
     (cmp @0 @1)))))
 
+/* Floating point comparisons can ignore signed zeros.  */
+(for cmp (tcc_comparison)
+ /* Simplify (X - X) CMP Y even with -frounding-math.  */
+ (simplify
+  (cmp (minus @0 @0) @1)
+  (if (FLOAT_TYPE_P (TREE_TYPE (@0))
+       && !tree_expr_maybe_nan_p (@0)
+       && !tree_expr_maybe_infinite_p (@0))
+   (cmp { build_zero_cst (TREE_TYPE (@0)); } @1)))
+ /* Simplify X CMP (Y - Y) even with -frounding-math.  */
+ (simplify
+  (cmp @0 (minus @1 @1))
+  (if (FLOAT_TYPE_P (TREE_TYPE (@1))
+       && !tree_expr_maybe_nan_p (@1)
+       && !tree_expr_maybe_infinite_p (@1))
+   (cmp @0 { build_zero_cst (TREE_TYPE (@1)); })))
+ /* Simplify (X * 0.0) CMP Y.  */
+ (simplify
+  (cmp (mult @0 real_zerop@1) @2)
+  (if (!tree_expr_maybe_nan_p (@0)
+       && !tree_expr_maybe_infinite_p (@0))
+   (cmp @1 @2)))
+ /* Simplify X CMP (Y * 0.0).  */
+ (simplify
+  (cmp @0 (mult @1 real_zerop@2))
+  (if (!tree_expr_maybe_nan_p (@1)
+       && !tree_expr_maybe_infinite_p (@0))
+   (cmp @0 @2))))
+
 /* Simplify (x < 0) ^ (y < 0) to (x ^ y) < 0 and
    (x >= 0) ^ (y >= 0) to (x ^ y) < 0.  */
 (for cmp (lt ge)
@@ -4743,7 +4772,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (simplify
   (cmp @0 @0)
   (if (! FLOAT_TYPE_P (TREE_TYPE (@0))
-       || ! HONOR_NANS (@0))
+       || ! tree_expr_maybe_nan_p (@0))
    { constant_boolean_node (true, type); }
    (if (cmp != EQ_EXPR
 	/* With -ftrapping-math conversion to EQ loses an exception.  */
@@ -4755,7 +4784,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cmp @0 @0)
   (if (cmp != NE_EXPR
        || ! FLOAT_TYPE_P (TREE_TYPE (@0))
-       || ! HONOR_NANS (@0))
+       || ! tree_expr_maybe_nan_p (@0))
    { constant_boolean_node (false, type); })))
 (for cmp (unle unge uneq)
  (simplify
@@ -4767,7 +4796,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (unordered @0 @0)))
 (simplify
  (ltgt @0 @0)
- (if (!flag_trapping_math)
+ (if (!flag_trapping_math || !tree_expr_maybe_nan_p (@0))
   { constant_boolean_node (false, type); }))
 
 /* x == ~x -> false */
diff --git a/gcc/testsuite/gcc.dg/fold-compare-9.c b/gcc/testsuite/gcc.dg/fold-compare-9.c
new file mode 100644
index 0000000..e56f63d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-compare-9.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x, double y) {
+    return (x * 0.0) < y;
+}
+
+/* { dg-final { scan-tree-dump " y_\[0-9\]\\(D\\) > 0.0" "optimized" } } */

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2022-03-26 18:52 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-14 19:25 [PATCH] Ignore (possible) signed zeros in operands of FP comparisons Roger Sayle
2022-03-15  7:29 ` Richard Biener
2022-03-15  8:03   ` Roger Sayle
2022-03-15 10:50     ` Richard Biener
2022-03-17 23:27     ` Jeff Law
2022-03-18  2:12       ` Andrew MacLeod
2022-03-18  7:43       ` Roger Sayle
2022-03-18 13:07         ` Andrew MacLeod
2022-03-18 18:07           ` Aldy Hernandez
2022-03-18 13:16       ` Andrew MacLeod
2022-03-18 16:01         ` Jeff Law
2022-03-18 18:33           ` Aldy Hernandez
2022-03-21 15:56             ` Aldy Hernandez
2022-03-26 18:52               ` Roger Sayle
2022-03-16  9:44   ` Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).