Add sinh(tanh(x)) and cosh(tanh(x)) rules

Message ID CAEFO=4C+BLJYGHNwuCbjdeY2Xj5KJkBeRRCKmSxqTUqwVokkag@mail.gmail.com
State New
Headers show
Series
  • Add sinh(tanh(x)) and cosh(tanh(x)) rules
Related show

Commit Message

Giuliano Augusto Faulin Belinassi Aug. 7, 2018, 8 p.m.
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.

Comments

Paul Koning Aug. 7, 2018, 8:29 p.m. | #1
> On Aug 7, 2018, at 4:00 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
> 
> 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.

What about non-IEEE targets that don't have "infinite" in their float representation?

	paul
Giuliano Augusto Faulin Belinassi Aug. 7, 2018, 8:42 p.m. | #2
That is a good question because I didn't know that such targets
exists. Any suggestion?


On Tue, Aug 7, 2018 at 5:29 PM, Paul Koning <paulkoning@comcast.net> wrote:
>
>
>> On Aug 7, 2018, at 4:00 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
>>
>> 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.
>
> What about non-IEEE targets that don't have "infinite" in their float representation?
>
>         paul
>
>
Paul Koning Aug. 8, 2018, 1:58 p.m. | #3
Now I'm puzzled.

I don't see how an infinite would show up in the original expression.  I don't know hyperbolic functions, so I just constructed a small test program, and the original vs. the substitution you mention are not at all similar.

	paul


> On Aug 7, 2018, at 4:42 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
> 
> That is a good question because I didn't know that such targets
> exists. Any suggestion?
> 
> 
> On Tue, Aug 7, 2018 at 5:29 PM, Paul Koning <paulkoning@comcast.net> wrote:
>> 
>> 
>>> On Aug 7, 2018, at 4:00 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
>>> 
>>> 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.
>> 
>> What about non-IEEE targets that don't have "infinite" in their float representation?
>> 
>>        paul
>> 
>>
Giuliano Augusto Faulin Belinassi Aug. 8, 2018, 6:57 p.m. | #4
Sorry about that. In the e-mail text field I wrote sinh(tanh(x)) and
cosh(tanh(x)) where it was supposed to be sinh(atanh(x)) and
cosh(atanh(x)), thus I am talking about the inverse hyperbolic tangent
function. The patch code and comments are still correct.

On Wed, Aug 8, 2018 at 10:58 AM, Paul Koning <paulkoning@comcast.net> wrote:
> Now I'm puzzled.
>
> I don't see how an infinite would show up in the original expression.  I don't know hyperbolic functions, so I just constructed a small test program, and the original vs. the substitution you mention are not at all similar.
>
>         paul
>
>
>> On Aug 7, 2018, at 4:42 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
>>
>> That is a good question because I didn't know that such targets
>> exists. Any suggestion?
>>
>>
>> On Tue, Aug 7, 2018 at 5:29 PM, Paul Koning <paulkoning@comcast.net> wrote:
>>>
>>>
>>>> On Aug 7, 2018, at 4:00 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
>>>>
>>>> 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.
>>>
>>> What about non-IEEE targets that don't have "infinite" in their float representation?
>>>
>>>        paul
>>>
>>>
>
Paul Koning Aug. 8, 2018, 7:55 p.m. | #5
Thanks.  Ok, so the expressions you gave are undefined for x==1, which says that substituting something that is also undefined for x==1 is permitted.  You can argue from "undefined" rather than relying on IEEE features like NaN or infinite.

	paul

> On Aug 8, 2018, at 2:57 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
> 
> Sorry about that. In the e-mail text field I wrote sinh(tanh(x)) and
> cosh(tanh(x)) where it was supposed to be sinh(atanh(x)) and
> cosh(atanh(x)), thus I am talking about the inverse hyperbolic tangent
> function. The patch code and comments are still correct.
> 
> On Wed, Aug 8, 2018 at 10:58 AM, Paul Koning <paulkoning@comcast.net> wrote:
>> Now I'm puzzled.
>> 
>> I don't see how an infinite would show up in the original expression.  I don't know hyperbolic functions, so I just constructed a small test program, and the original vs. the substitution you mention are not at all similar.
>> 
>>        paul
>> 
>> 
>>> On Aug 7, 2018, at 4:42 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
>>> 
>>> That is a good question because I didn't know that such targets
>>> exists. Any suggestion?
>>> 
>>> 
>>> On Tue, Aug 7, 2018 at 5:29 PM, Paul Koning <paulkoning@comcast.net> wrote:
>>>> 
>>>> 
>>>>> On Aug 7, 2018, at 4:00 PM, Giuliano Augusto Faulin Belinassi <giuliano.belinassi@usp.br> wrote:
>>>>> 
>>>>> 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.
>>>> 
>>>> What about non-IEEE targets that don't have "infinite" in their float representation?
>>>> 
>>>>       paul
>>>> 
>>>> 
>>

Patch

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" } } */