public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fold (a > 0 ? 1.0 : -1.0) into copysign (1.0, a) and a * copysign (1.0, a) into abs(a)
@ 2017-06-24 21:56 Andrew Pinski
  2017-06-25  8:28 ` Marc Glisse
  0 siblings, 1 reply; 16+ messages in thread
From: Andrew Pinski @ 2017-06-24 21:56 UTC (permalink / raw)
  To: GCC Patches

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

Hi,
  I decided to split my previous patch into two different patches, one
for floating point and one for integer.  This is the floating point
version as we can use copysign here which should allow for more cases
to be optimized and even by a phiopt which uses match-and-simplify (I
hope to be able to submit that during stage 1).

This patch adds the following transformations:
Transform (X > 0.0 ? 1.0 : -1.0) into copysign(1, X).
Transform (X >= 0.0 ? 1.0 : -1.0) into copysign(1, X).
Transform (X < 0.0 ? 1.0 : -1.0) into copysign(1,-X).
Transform (X <= 0.0 ? 1.0 : -1.0) into copysign(1,-X).
Transform (X > 0.0 ? -1.0 : 1.0) into copysign(1,-X).
Transform (X >= 0.0 ? -1.0 : 1.0) into copysign(1,-X).
Transform (X < 0.0 ? -1.0 : 1.0) into copysign(1,X).
Transform (X <= 0.0 ? -1.0 : 1.0) into copysign(1,X).

Transform X * copysign (1.0, X) into abs(X).
Transform X * copysign (1.0, -X) into -abs(X).

Transform copysign (-1.0, X) into copysign (1.0, X).

The last one is there so if someone decides to writes -1.0 instead of
1.0 in the code we would get the optimization still.

OK?  Bootstrapped and tested on aarch64-linux-gnu with no regressions.

Thanks,
Andrew Pinski

ChangeLog:
* match.pd (X >/>=/</<= 0 ? 1.0 : -1.0): New patterns.
(X * copysign (1.0, X)): New pattern.
(X * copysign (1.0, -X)): New pattern.
(copysign (-1.0, X)): New pattern.

testsuite/ChangeLog:
* gcc.dg/tree-ssa/copy-sign-1.c: New testcase.
* gcc.dg/tree-ssa/copy-sign-2.c: New testcase.
* gcc.dg/tree-ssa/mult-abs-2.c: New testcase.

[-- Attachment #2: copysign-1.diff.txt --]
[-- Type: text/plain, Size: 4852 bytes --]

Index: match.pd
===================================================================
--- match.pd	(revision 249626)
+++ match.pd	(working copy)
@@ -155,6 +155,57 @@
            || !COMPLEX_FLOAT_TYPE_P (type)))
    (negate @0)))
 
+(for cmp (gt ge lt le)
+     outp (convert convert negate negate)
+     outn (negate negate convert convert)
+ /* Transform (X > 0.0 ? 1.0 : -1.0) into copysign(1, X). */
+ /* Transform (X >= 0.0 ? 1.0 : -1.0) into copysign(1, X). */
+ /* Transform (X < 0.0 ? 1.0 : -1.0) into copysign(1,-X). */
+ /* Transform (X <= 0.0 ? 1.0 : -1.0) into copysign(1,-X). */
+ (simplify
+  (cond (cmp @0 real_zerop) real_onep real_minus_onep)
+  (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)
+       && types_match (type, TREE_TYPE (@0)))
+   (switch
+    (if (types_match (type, float_type_node))
+     (BUILT_IN_COPYSIGNF { build_one_cst (type); } (outp @0)))
+    (if (types_match (type, double_type_node))
+     (BUILT_IN_COPYSIGN { build_one_cst (type); } (outp @0)))
+    (if (types_match (type, long_double_type_node))
+     (BUILT_IN_COPYSIGNL { build_one_cst (type); } (outp @0))))))
+ /* Transform (X > 0.0 ? -1.0 : 1.0) into copysign(1,-X). */
+ /* Transform (X >= 0.0 ? -1.0 : 1.0) into copysign(1,-X). */
+ /* Transform (X < 0.0 ? -1.0 : 1.0) into copysign(1,X). */
+ /* Transform (X <= 0.0 ? -1.0 : 1.0) into copysign(1,X). */
+ (simplify
+  (cond (cmp @0 real_zerop) real_minus_onep real_onep)
+  (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type)
+       && types_match (type, TREE_TYPE (@0)))
+   (switch
+    (if (types_match (type, float_type_node))
+     (BUILT_IN_COPYSIGNF { build_one_cst (type); } (outn @0)))
+    (if (types_match (type, double_type_node))
+     (BUILT_IN_COPYSIGN { build_one_cst (type); } (outn @0)))
+    (if (types_match (type, long_double_type_node))
+     (BUILT_IN_COPYSIGNL { build_one_cst (type); } (outn @0)))))))
+
+/* Transform X * copysign (1.0, X) into abs(X). */
+(simplify
+ (mult:c @0 (COPYSIGN real_onep @0))
+ (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type))
+  (abs @0)))
+
+/* Transform X * copysign (1.0, -X) into -abs(X). */
+(simplify
+ (mult:c @0 (COPYSIGN real_onep (negate @0)))
+ (if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type))
+  (negate (abs @0))))
+
+/* Transform copysign (-1.0, X) into copysign (1.0, X). */
+(simplify
+ (COPYSIGN real_minus_onep @0)
+ (COPYSIGN { build_one_cst (type); } @0))
+
 /* X * 1, X / 1 -> X.  */
 (for op (mult trunc_div ceil_div floor_div round_div exact_div)
   (simplify
Index: testsuite/gcc.dg/tree-ssa/copy-sign-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/copy-sign-1.c	(nonexistent)
+++ testsuite/gcc.dg/tree-ssa/copy-sign-1.c	(working copy)
@@ -0,0 +1,35 @@
+/* { dg-options "-O2 -ffast-math -fdump-tree-gimple" } */
+/* { dg-do compile } */
+float f(float x)
+{
+  return (x > 0.f ? -1.f : 1.f);
+}
+float f1(float x)
+{
+  return (x > 0.f ? 1.f : -1.f);
+}
+float g(float x)
+{
+  return (x >= 0.f ? -1.f : 1.f);
+}
+float g1(float x)
+{
+  return (x >= 0.f ? 1.f : -1.f);
+}
+float h(float x)
+{
+  return (x < 0.f ? -1.f : 1.f);
+}
+float h1(float x)
+{
+  return (x < 0.f ? 1.f : -1.f);
+}
+float i(float x)
+{
+  return (x <= 0.f ? -1.f : 1.f);
+}
+float i1(float x)
+{
+  return (x <= 0.f ? 1.f : -1.f);
+}
+/* { dg-final { scan-tree-dump-times "copysign" 8 "gimple"} } */
Index: testsuite/gcc.dg/tree-ssa/copy-sign-2.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/copy-sign-2.c	(nonexistent)
+++ testsuite/gcc.dg/tree-ssa/copy-sign-2.c	(working copy)
@@ -0,0 +1,13 @@
+/* { dg-options "-O2 -ffast-math -fdump-tree-optimized" } */
+/* { dg-do compile } */
+float f(float x)
+{
+  float t = __builtin_copysignf (1.0f, x);
+  return x * t;
+}
+float f1(float x)
+{
+  float t = __builtin_copysignf (1.0f, -x);
+  return x * t;
+}
+/* { dg-final { scan-tree-dump-times "ABS" 2 "optimized"} } */
Index: testsuite/gcc.dg/tree-ssa/mult-abs-2.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/mult-abs-2.c	(nonexistent)
+++ testsuite/gcc.dg/tree-ssa/mult-abs-2.c	(working copy)
@@ -0,0 +1,35 @@
+/* { dg-options "-O2 -ffast-math -fdump-tree-gimple" } */
+/* { dg-do compile } */
+float f(float x)
+{
+  return x * (x > 0.f ? -1.f : 1.f);
+}
+float f1(float x)
+{
+  return x * (x > 0.f ? 1.f : -1.f);
+}
+float g(float x)
+{
+  return x * (x >= 0.f ? -1.f : 1.f);
+}
+float g1(float x)
+{
+  return x * (x >= 0.f ? 1.f : -1.f);
+}
+float h(float x)
+{
+  return x * (x < 0.f ? -1.f : 1.f);
+}
+float h1(float x)
+{
+  return x * (x < 0.f ? 1.f : -1.f);
+}
+float i(float x)
+{
+  return x * (x <= 0.f ? -1.f : 1.f);
+}
+float i1(float x)
+{
+  return x * (x <= 0.f ? 1.f : -1.f);
+}
+/* { dg-final { scan-tree-dump-times "ABS" 8 "gimple"} } */

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

end of thread, other threads:[~2017-06-29 18:49 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-24 21:56 [PATCH] Fold (a > 0 ? 1.0 : -1.0) into copysign (1.0, a) and a * copysign (1.0, a) into abs(a) Andrew Pinski
2017-06-25  8:28 ` Marc Glisse
2017-06-25 18:18   ` Andrew Pinski
2017-06-25 21:28     ` Andrew Pinski
2017-06-27  8:49       ` Richard Biener
2017-06-27 14:52       ` Tamar Christina
2017-06-27 14:57         ` Richard Biener
2017-06-27 17:52           ` Andrew Pinski
2017-06-28  7:37             ` Jakub Jelinek
2017-06-28  7:57               ` Uros Bizjak
2017-06-28  8:50       ` Christophe Lyon
2017-06-28  9:29         ` Richard Biener
2017-06-29 18:49       ` H.J. Lu
2017-06-26  8:45   ` Richard Sandiford
2017-06-26 15:22     ` Joseph Myers
2017-06-26 18:23       ` 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).