This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Add sinh(tanh(x)) and cosh(tanh(x)) rules
- From: Giuliano Augusto Faulin Belinassi <giuliano dot belinassi at usp dot br>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 7 Aug 2018 17:00:07 -0300
- Subject: [PATCH] Add sinh(tanh(x)) and cosh(tanh(x)) rules
Related with bug 86829, but for hyperbolic trigonometric functions.
This patch adds substitution rules to both sinh(tanh(x)) -> x / sqrt(1
- x*x) and cosh(tanh(x)) -> 1 / sqrt(1 - x*x). Notice that the both
formulas has division by 0, but it causes no harm because 1/(+0) ->
+infinity, thus the math is still safe.
Changelog:
2018-08-07 Giuliano Belinassi <giuliano.belinassi@usp.br>
* match.pd: add simplification rules to sinh(atanh(x)) and cosh(atanh(x)).
All tests added by this patch runs without errors in trunk, however,
there are tests unrelated with this patch that fails in my x86_64
Ubuntu 18.04.
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revisão 263359)
+++ gcc/match.pd (cópia de trabalho)
@@ -4219,6 +4219,25 @@
(mult:c (TAN:s @0) (COS:s @0))
(SIN @0))
+ /* Simplify sinh(atanh(x)) -> x / sqrt(1 - x*x). */
+ (for sins (SINH)
+ atans (ATANH)
+ sqrts (SQRT)
+ (simplify
+ (sins (atans:s @0))
+ (rdiv @0 (sqrts (minus {build_one_cst (type);}
+ (mult @0 @0))))))
+
+ /* Simplify cosh(atanh(x)) -> 1 / sqrt(1 - x*x). */
+ (for coss (COSH)
+ atans (ATANH)
+ sqrts (SQRT)
+ (simplify
+ (coss (atans:s @0))
+ (rdiv {build_one_cst (type);}
+ (sqrts (minus {build_one_cst (type);}
+ (mult @0 @0))))))
+
/* Simplify x * pow(x,c) -> pow(x,c+1). */
(simplify
(mult:c @0 (POW:s @0 REAL_CST@1))
Index: gcc/testsuite/gcc.dg/sinhtanh-1.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhtanh-1.c (nonexistent)
+++ gcc/testsuite/gcc.dg/sinhtanh-1.c (cópia de trabalho)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double sinh(double x);
+extern double atanh(double x);
+
+double __attribute__ ((noinline))
+sinhatanh_(double x)
+{
+ return sinh(atanh(x));
+}
+
+/* There should be no calls to sinh nor atanh */
+/* { dg-final { scan-tree-dump-not "sinh " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "atanh " "optimized" } } */
Index: gcc/testsuite/gcc.dg/sinhtanh-2.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhtanh-2.c (nonexistent)
+++ gcc/testsuite/gcc.dg/sinhtanh-2.c (cópia de trabalho)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double cosh(double x);
+extern double atanh(double x);
+
+double __attribute__ ((noinline))
+coshatanh_(double x)
+{
+ return cosh(atanh(x));
+}
+
+/* There should be no calls to cosh nor atanh */
+/* { dg-final { scan-tree-dump-not "cosh " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "atanh " "optimized" } } */
Index: gcc/testsuite/gcc.dg/sinhtanh-3.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhtanh-3.c (nonexistent)
+++ gcc/testsuite/gcc.dg/sinhtanh-3.c (cópia de trabalho)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double sinh(double x);
+extern double atanh(double x);
+
+double __attribute__ ((noinline))
+sinhatanh_(double x)
+{
+ double atgh = atanh(x);
+ return sinh(atgh) + atgh;
+}
+
+/* There should be calls to both sinh and atanh */
+/* { dg-final { scan-tree-dump "sinh " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanh " "optimized" } } */
Index: gcc/testsuite/gcc.dg/sinhtanh-4.c
===================================================================
--- gcc/testsuite/gcc.dg/sinhtanh-4.c (nonexistent)
+++ gcc/testsuite/gcc.dg/sinhtanh-4.c (cópia de trabalho)
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double cosh(double x);
+extern double atanh(double x);
+
+double __attribute__ ((noinline))
+coshatanh_(double x)
+{
+ double atgh = atanh(x);
+ return cosh(atgh) + atgh;
+}
+
+/* There should be calls to both cosh and atanh */
+/* { dg-final { scan-tree-dump "cosh " "optimized" } } */
+/* { dg-final { scan-tree-dump "atanh " "optimized" } } */