This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

patch to bug #86829


Closes bug #86829

Description: Adds substitution rules for both sin(atan(x)) and
cos(atan(x)). These formulas are replaced by x / sqrt(x*x + 1) and 1 /
sqrt(x*x + 1) respectively, providing up to 10x speedup. This identity
can be proved mathematically.

Changelog:

2018-08-03  Giuliano Belinassi <giuliano.belinassi@usp.br>

    * match.pd: add simplification rules to sin(atan(x)) and cos(atan(x)).

Bootstrap and Testing:
There were no unexpected failures in a proper testing in GCC 8.1.0
under a x86_64 running Ubuntu 18.04.

Attachment: test_results.txt
Description: Text document

diff -rupN -u gcc_orig/gcc/match.pd gcc_mod/gcc/match.pd
--- gcc_orig/gcc/match.pd	2018-04-20 07:31:23.000000000 -0300
+++ gcc_mod/gcc/match.pd	2018-08-03 15:25:32.307520365 -0300
@@ -4174,6 +4174,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && ! HONOR_INFINITIES (@0))
    (rdiv { build_one_cst (type); } (COS @0))))
 
+ /* Simplify sin(atan(x)) -> x / sqrt(x*x + 1). */
+ (for sins (SIN)
+      atans (ATAN)
+      sqrts (SQRT)
+  (simplify
+   (sins (atans:s @0))
+   (rdiv @0 (sqrts (plus (mult @0 @0) 
+       {build_one_cst (type);})))))
+ 
+ 
+ /* Simplify cos(atan(x)) -> 1 / sqrt(x*x + 1). */
+ (for coss (COS)
+      atans (ATAN)
+      sqrts (SQRT)
+  (simplify
+   (coss (atans:s @0))
+   (rdiv {build_one_cst (type);} 
+       (sqrts (plus (mult @0 @0) {build_one_cst (type);})))))
+
  /* Simplify pow(x,y) * pow(x,z) -> pow(x,y+z). */
  (simplify
   (mult (POW:s @0 @1) (POW:s @0 @2))
diff -rupN -u gcc_orig/gcc/testsuite/gcc.dg/sinatan-1.c gcc_mod/gcc/testsuite/gcc.dg/sinatan-1.c
--- gcc_orig/gcc/testsuite/gcc.dg/sinatan-1.c	1969-12-31 21:00:00.000000000 -0300
+++ gcc_mod/gcc/testsuite/gcc.dg/sinatan-1.c	2018-08-02 19:06:23.632015000 -0300
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double sin(double x);
+extern double atan(double x);
+
+double __attribute__ ((noinline)) 
+sinatan_(double x)
+{
+    return sin(atan(x));
+}
+
+/* There should be no calls to sin nor atan */
+/* { dg-final { scan-tree-dump-not "sin " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "atan " "optimized" } } */
diff -rupN -u gcc_orig/gcc/testsuite/gcc.dg/sinatan-2.c gcc_mod/gcc/testsuite/gcc.dg/sinatan-2.c
--- gcc_orig/gcc/testsuite/gcc.dg/sinatan-2.c	1969-12-31 21:00:00.000000000 -0300
+++ gcc_mod/gcc/testsuite/gcc.dg/sinatan-2.c	2018-08-02 19:06:29.579990000 -0300
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double cos(double x);
+extern double atan(double x);
+
+double __attribute__ ((noinline)) 
+cosatan_(double x)
+{
+    return cos(atan(x));
+}
+
+/* There should be no calls to sin nor atan */
+/* { dg-final { scan-tree-dump-not "cos " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "atan " "optimized" } } */
diff -rupN -u gcc_orig/gcc/testsuite/gcc.dg/sinatan-3.c gcc_mod/gcc/testsuite/gcc.dg/sinatan-3.c
--- gcc_orig/gcc/testsuite/gcc.dg/sinatan-3.c	1969-12-31 21:00:00.000000000 -0300
+++ gcc_mod/gcc/testsuite/gcc.dg/sinatan-3.c	2018-08-02 19:17:11.663657000 -0300
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double sin(double x);
+extern double atan(double x);
+
+double __attribute__ ((noinline)) 
+sinatan_(double x)
+{
+    double atg = atan(x);
+    return sin(atg) + atg;
+}
+
+/* There should be calls to both sin and atan */
+/* { dg-final { scan-tree-dump "sin " "optimized" } } */
+/* { dg-final { scan-tree-dump "atan " "optimized" } } */
diff -rupN -u gcc_orig/gcc/testsuite/gcc.dg/sinatan-4.c gcc_mod/gcc/testsuite/gcc.dg/sinatan-4.c
--- gcc_orig/gcc/testsuite/gcc.dg/sinatan-4.c	1969-12-31 21:00:00.000000000 -0300
+++ gcc_mod/gcc/testsuite/gcc.dg/sinatan-4.c	2018-08-02 19:17:01.091726000 -0300
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math -fdump-tree-optimized" } */
+
+extern double cos(double x);
+extern double atan(double x);
+
+double __attribute__ ((noinline)) 
+cosatan_(double x)
+{
+    double atg = atan(x);
+    return cos(atg) + atg;
+}
+
+/* There should be calls to both cos and atan */
+/* { dg-final { scan-tree-dump "cos " "optimized" } } */
+/* { dg-final { scan-tree-dump "atan " "optimized" } } */

Attachment: Changelog
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]