diff mbox series

[v4] Add sinh(atanh(x)) and cosh(atanh(x)) optimizations

Message ID CAEFO=4CcNCq2NWqx1THCw7C5AU23UkRdO0O=UN71=hKF1CsVZA@mail.gmail.com
State New
Headers show
Series [v4] Add sinh(atanh(x)) and cosh(atanh(x)) optimizations | expand

Commit Message

Giuliano Belinassi Nov. 27, 2018, 7:38 p.m. UTC
Only do this optimization if funsafe-math and -fno-math-errno are
enabled, as pointed in the previous iteration.

Also added one more test case to ensure that fno-math-errno is
required for the optimization.

Special thanks for Wilco Dijsktra for all his help :-)

gcc/ChangeLog
2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>

    * match.pd (sinh (atanh (x))): New simplification rules.
    (cosh (atanh (x))): Likewise.

gcc/testsuite/ChangeLog
2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>

    * gcc.dg/sinhatanh-1.c: New test.
    * gcc.dg/sinhatanh-2.c: New test.
    * gcc.dg/sinhatanh-3.c: New test.

Comments

Jeff Law Nov. 29, 2018, 4:37 a.m. UTC | #1
On 11/27/18 12:38 PM, Giuliano Augusto Faulin Belinassi wrote:
> Only do this optimization if funsafe-math and -fno-math-errno are
> enabled, as pointed in the previous iteration.
> 
> Also added one more test case to ensure that fno-math-errno is
> required for the optimization.
> 
> Special thanks for Wilco Dijsktra for all his help :-)
> 
> gcc/ChangeLog
> 2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>
> 
>     * match.pd (sinh (atanh (x))): New simplification rules.
>     (cosh (atanh (x))): Likewise.
> 
> gcc/testsuite/ChangeLog
> 2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>
> 
>     * gcc.dg/sinhatanh-1.c: New test.
>     * gcc.dg/sinhatanh-2.c: New test.
>     * gcc.dg/sinhatanh-3.c: New test.
> 
> 
> sinhatanhv4.patch
> 
> Index: gcc/match.pd
> ===================================================================
> --- gcc/match.pd	(revision 266469)
> +++ gcc/match.pd	(working copy)
> @@ -4342,6 +4342,25 @@
>        (rdiv { t_one; } (sqrts (plus (mult @0 @0) { t_one; })))
>        (copysigns { t_zero; } @0))))))
>  
> + (if (!flag_errno_math)
You're missing the flag_unsafe_math_optimizations check AFAICT.  Right?

jeff
Giuliano Belinassi Nov. 29, 2018, 10:34 a.m. UTC | #2
Hi,

Please check line 4102 in match.pd. Notice that

    (if (flag_unsafe_math_optimizations)

And my code is inside that if :-)

Giuliano.
On Thu, Nov 29, 2018 at 2:37 AM Jeff Law <law@redhat.com> wrote:
>
> On 11/27/18 12:38 PM, Giuliano Augusto Faulin Belinassi wrote:
> > Only do this optimization if funsafe-math and -fno-math-errno are
> > enabled, as pointed in the previous iteration.
> >
> > Also added one more test case to ensure that fno-math-errno is
> > required for the optimization.
> >
> > Special thanks for Wilco Dijsktra for all his help :-)
> >
> > gcc/ChangeLog
> > 2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>
> >
> >     * match.pd (sinh (atanh (x))): New simplification rules.
> >     (cosh (atanh (x))): Likewise.
> >
> > gcc/testsuite/ChangeLog
> > 2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>
> >
> >     * gcc.dg/sinhatanh-1.c: New test.
> >     * gcc.dg/sinhatanh-2.c: New test.
> >     * gcc.dg/sinhatanh-3.c: New test.
> >
> >
> > sinhatanhv4.patch
> >
> > Index: gcc/match.pd
> > ===================================================================
> > --- gcc/match.pd      (revision 266469)
> > +++ gcc/match.pd      (working copy)
> > @@ -4342,6 +4342,25 @@
> >        (rdiv { t_one; } (sqrts (plus (mult @0 @0) { t_one; })))
> >        (copysigns { t_zero; } @0))))))
> >
> > + (if (!flag_errno_math)
> You're missing the flag_unsafe_math_optimizations check AFAICT.  Right?
>
> jeff
Jeff Law Nov. 29, 2018, 3:23 p.m. UTC | #3
On 11/29/18 3:34 AM, Giuliano Augusto Faulin Belinassi wrote:
> Hi,
> 
> Please check line 4102 in match.pd. Notice that
> 
>     (if (flag_unsafe_math_optimizations)
> 
> And my code is inside that if :-)
Ugh.  I went backwards looking for something like that and missed it :-)
 I may have not gone back far enough...

I think this is ready to go.  I expect to commit it shortly.

jeff
Jeff Law Nov. 29, 2018, 3:30 p.m. UTC | #4
On 11/27/18 12:38 PM, Giuliano Augusto Faulin Belinassi wrote:
> Only do this optimization if funsafe-math and -fno-math-errno are
> enabled, as pointed in the previous iteration.
> 
> Also added one more test case to ensure that fno-math-errno is
> required for the optimization.
> 
> Special thanks for Wilco Dijsktra for all his help :-)
> 
> gcc/ChangeLog
> 2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>
> 
>     * match.pd (sinh (atanh (x))): New simplification rules.
>     (cosh (atanh (x))): Likewise.
> 
> gcc/testsuite/ChangeLog
> 2018-11-27  Giuliano Belinassi  <giuliano.belinassi@usp.br>
> 
>     * gcc.dg/sinhatanh-1.c: New test.
>     * gcc.dg/sinhatanh-2.c: New test.
>     * gcc.dg/sinhatanh-3.c: New test.
Arguably you'd want to extend the -2 and -3 tests to verify the number
of calls to sinh, cosh and atanh is what you expect.  An alternate would
be verifying there are no sqrt calls.  But I think that can be handled
as a follow-up if you wanted to improve the test.


I've installed the patch.  THanks for your persistence.  This probably
took a lot longer than anyone anticipated.

jeff
diff mbox series

Patch

Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 266469)
+++ gcc/match.pd	(working copy)
@@ -4342,6 +4342,25 @@ 
       (rdiv { t_one; } (sqrts (plus (mult @0 @0) { t_one; })))
       (copysigns { t_zero; } @0))))))
 
+ (if (!flag_errno_math)
+  /* Simplify sinh(atanh(x)) -> x / sqrt((1 - x)*(1 + x)). */
+  (for sinhs (SINH)
+       atanhs (ATANH)
+       sqrts (SQRT)
+   (simplify
+    (sinhs (atanhs:s @0))
+    (with { tree t_one = build_one_cst (type); }
+    (rdiv @0 (sqrts (mult (minus { t_one; } @0) (plus { t_one; } @0)))))))
+
+  /* Simplify cosh(atanh(x)) -> 1 / sqrt((1 - x)*(1 + x)) */
+  (for coshs (COSH)
+       atanhs (ATANH)
+       sqrts (SQRT)
+   (simplify
+    (coshs (atanhs:s @0))
+    (with { tree t_one = build_one_cst (type); }
+    (rdiv { t_one; } (sqrts (mult (minus { t_one; } @0) (plus { t_one; } @0))))))))
+
 /* cabs(x+0i) or cabs(0+xi) -> abs(x).  */
 (simplify
  (CABS (complex:C @0 real_zerop@1))
Index: gcc/testsuite/gcc.dg/sinhatanh-1.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhatanh-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/sinhatanh-1.c	(working copy)
@@ -0,0 +1,62 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-optimized" } */
+
+extern float sinhf (float);
+extern float coshf (float);
+extern float atanhf (float);
+extern float sqrtf (float);
+extern double sinh (double);
+extern double cosh (double);
+extern double atanh (double);
+extern double sqrt (double);
+extern long double sinhl (long double);
+extern long double coshl (long double);
+extern long double atanhl (long double);
+extern long double sqrtl (long double);
+
+double __attribute__ ((noinline))
+sinhatanh_ (double x)
+{
+    return sinh (atanh (x));
+}
+
+double __attribute__ ((noinline))
+coshatanh_ (double x)
+{
+    return cosh (atanh (x));
+}
+
+float __attribute__ ((noinline))
+sinhatanhf_(float x)
+{
+    return sinhf (atanhf (x));
+}
+
+float __attribute__ ((noinline))
+coshatanhf_(float x)
+{
+    return coshf (atanhf (x));
+}
+
+long double __attribute__ ((noinline))
+sinhatanhl_ (long double x)
+{
+    return sinhl (atanhl (x));
+}
+
+long double __attribute__ ((noinline))
+coshatanhl_ (long double x)
+{
+    return coshl (atanhl (x));
+}
+
+/* There must be no calls to sinh, cosh, or atanh */
+/* {dg-final { scan-tree-dump-not "sinh " "optimized" } } */
+/* {dg-final { scan-tree-dump-not "cosh " "optimized" } } */
+/* {dg-final { scan-tree-dump-not "atanh " "optimized" }} */
+/* {dg-final { scan-tree-dump-not "sinfh " "optimized" } } */
+/* {dg-final { scan-tree-dump-not "cosfh " "optimized" } } */
+/* {dg-final { scan-tree-dump-not "atanfh " "optimized" }} */
+/* {dg-final { scan-tree-dump-not "sinlh " "optimized" } } */
+/* {dg-final { scan-tree-dump-not "coslh " "optimized" } } */
+/* {dg-final { scan-tree-dump-not "atanlh " "optimized" }} */
Index: gcc/testsuite/gcc.dg/sinhatanh-2.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhatanh-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/sinhatanh-2.c	(working copy)
@@ -0,0 +1,68 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-optimized" } */
+
+extern float sinhf (float);
+extern float coshf (float);
+extern float atanhf (float);
+extern float sqrtf (float);
+extern double sinh (double);
+extern double cosh (double);
+extern double atanh (double);
+extern double sqrt (double);
+extern long double sinhl (long double);
+extern long double coshl (long double);
+extern long double atanhl (long double);
+extern long double sqrtl (long double);
+
+float __attribute__ ((noinline))
+coshatanhf_(float x)
+{
+    float atg = atanhf(x);
+    return coshf(atg) + atg;
+}
+
+double __attribute__ ((noinline))
+cosatan_(double x)
+{
+    double atg = atanh(x);
+    return cosh(atg) + atg;
+}
+
+long double __attribute__ ((noinline))
+cosatanl_(long double x)
+{
+    long double atg = atanhl(x);
+    return coshl(atg) + atg;
+}
+
+float __attribute__ ((noinline))
+sinatanf_(float x)
+{
+    float atg = atanhf(x);
+    return sinhf(atg) + atg;
+}
+
+double __attribute__ ((noinline))
+sinatan_(double x)
+{
+    double atg = atanh(x);
+    return sinh(atg) + atg;
+}
+
+long double __attribute__ ((noinline))
+sinatanl_(long double x)
+{
+    long double atg = atanhl(x);
+    return sinhl(atg) + atg;
+}
+
+/* There should be calls to sinh, cosh and atanh */
+/* { dg-final { scan-tree-dump "cosh " "optimized" } } */
+/* { dg-final { scan-tree-dump "sinh " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanh " "optimized" } } */
+/* { dg-final { scan-tree-dump "coshf " "optimized" } } */
+/* { dg-final { scan-tree-dump "sinhf " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanhf " "optimized" } } */
+/* { dg-final { scan-tree-dump "coshl " "optimized" } } */
+/* { dg-final { scan-tree-dump "sinhl " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanhl " "optimized" } } */
Index: gcc/testsuite/gcc.dg/sinhatanh-3.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhatanh-3.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/sinhatanh-3.c	(working copy)
@@ -0,0 +1,62 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fmath-errno -fdump-tree-optimized" } */
+
+extern float sinhf (float);
+extern float coshf (float);
+extern float atanhf (float);
+extern float sqrtf (float);
+extern double sinh (double);
+extern double cosh (double);
+extern double atanh (double);
+extern double sqrt (double);
+extern long double sinhl (long double);
+extern long double coshl (long double);
+extern long double atanhl (long double);
+extern long double sqrtl (long double);
+
+double __attribute__ ((noinline))
+sinhatanh_ (double x)
+{
+    return sinh (atanh (x));
+}
+
+double __attribute__ ((noinline))
+coshatanh_ (double x)
+{
+    return cosh (atanh (x));
+}
+
+float __attribute__ ((noinline))
+sinhatanhf_(float x)
+{
+    return sinhf (atanhf (x));
+}
+
+float __attribute__ ((noinline))
+coshatanhf_(float x)
+{
+    return coshf (atanhf (x));
+}
+
+long double __attribute__ ((noinline))
+sinhatanhl_ (long double x)
+{
+    return sinhl (atanhl (x));
+}
+
+long double __attribute__ ((noinline))
+coshatanhl_ (long double x)
+{
+    return coshl (atanhl (x));
+}
+
+/* There should be calls to sinh, cosh and atanh */
+/* { dg-final { scan-tree-dump "cosh " "optimized" } } */
+/* { dg-final { scan-tree-dump "sinh " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanh " "optimized" } } */
+/* { dg-final { scan-tree-dump "coshf " "optimized" } } */
+/* { dg-final { scan-tree-dump "sinhf " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanhf " "optimized" } } */
+/* { dg-final { scan-tree-dump "coshl " "optimized" } } */
+/* { dg-final { scan-tree-dump "sinhl " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanhl " "optimized" } } */