On Fri, Jan 31, 2020 at 12:53 AM Vitor Guidi <vitor.gu...@usp.br> wrote: > > Hi. > > This patch adds a new optimization to avoid the redundant calculation > tanh(x)/sinh(x) by replacing it for 1.0/cosh(x), for all cases where x is a > double, a long double or a float. > > There should be no need for numerical stability testing, since the division > of the two functions only adds numerical noise. The correctness of the > operation is justified by the definition of tanh(x) = sinh(x)/cosh(x). If > you think it is wise to write a test, please let me know. > > As far as testing goes, I ran a check-gcc test under Ubuntu 19.04 by adding > the test in tanhbysinh.c and found no issues.
OK for GCC 11, please either attach patches or avoid quoting them. > Best regards, > > Vitor. > > in gcc/ChangeLog: > 2020-08-28 Vitor Guidi <vitor.gu...@usp.br> > > * match.pd: New substitution rule for tanh(x)/sinh(x) -> > 1.0/cosh(x). > > in gcc/testsuite/ChangeLog: > 2020-08-28 Vitor Guidi <vitor.gu...@usp.br> > > * gcc.dg/tanhbysinh.c (new): Verify if simplification is applied. Just use :New testcase, without any function designation. > > > diff --git gcc/match.pd gcc/match.pd > > index 5fee394e7af..3933fcaf9fa 100644 > > --- gcc/match.pd > > +++ gcc/match.pd > > @@ -5069,6 +5069,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > (rdiv (SINH:s @0) (COSH:s @0)) > > (TANH @0)) > > > > + /* Simplify tanh (x) / sinh (x) -> 1.0 / cosh (x). */ > > + (simplify > > + (rdiv (TANH @0) (SINH @0)) > > + (rdiv {build_one_cst (type);} (COSH @0))) > > + > > /* Simplify cos(x) / sin(x) -> 1 / tan(x). */ > > (simplify > > (rdiv (COS:s @0) (SIN:s @0)) > > diff --git gcc/testsuite/gcc.dg/tanhbysinh.c > gcc/testsuite/gcc.dg/tanhbysinh.c > > new file mode 100644 > > index 00000000000..fde72c2f93b > > --- /dev/null > > +++ gcc/testsuite/gcc.dg/tanhbysinh.c > > @@ -0,0 +1,40 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-Ofast -fdump-tree-optimized" } */ > > + > > +extern float sinhf (float); > > +extern float tanhf (float); > > +extern double sinh (double); > > +extern double tanh (double); > > +extern long double sinhl (long double); > > +extern long double tanhl (long double); > > + > > +double __attribute__ ((noinline)) > > +tanhbysinh_ (double x) > > +{ > > + return tanh (x) / sinh (x); > > +} > > + > > +float __attribute__ ((noinline)) > > +tanhbysinhf_ (float x) > > +{ > > + return tanhf (x) / sinhf (x); > > +} > > + > > +long double __attribute__ ((noinline)) > > +tanhbysinhl_ (long double x) > > +{ > > + return tanhl (x) / sinhl (x); > > +} > > + > > + > > +/* There must be no calls to sinh or atanh */ > > +/* There must be calls to cosh */ > > +/* {dg-final { scan-tree-dump-not "sinh " "optimized" } } */ > > +/* {dg-final { scan-tree-dump-not "tanh " "optimized" }} */ > > +/* {dg-final { scan-tree-dump-not "sinhf " "optimized" } } */ > > +/* {dg-final { scan-tree-dump-not "tanhf " "optimized" }} */ > > +/* {dg-final { scan-tree-dump-not "sinhl " "optimized" } } */ > > +/* {dg-final { scan-tree-dump-not "tanhl " "optimized" }} */ > > +/* { dg-final { scan-tree-dump "cosh " "optimized" } } */ > > +/* { dg-final { scan-tree-dump "coshf " "optimized" } } */ > > +/* { dg-final { scan-tree-dump "coshl " "optimized" } } */ > > \ No newline at end of file