aboutsummaryrefslogtreecommitdiff
path: root/gcc/real.c
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2018-10-11 21:06:12 +0000
committerJeff Law <law@gcc.gnu.org>2018-10-11 15:06:12 -0600
commit121ef08b0b964ff4e7072a6af14613e68788abc4 (patch)
treee967a89e2270c12ad7a8fa8d6fbf6f4a32132efd /gcc/real.c
parentea010af6b4d780261b791999e43ba056edce2af0 (diff)
downloadgcc-121ef08b0b964ff4e7072a6af14613e68788abc4.zip
gcc-121ef08b0b964ff4e7072a6af14613e68788abc4.tar.gz
gcc-121ef08b0b964ff4e7072a6af14613e68788abc4.tar.bz2
re PR tree-optimization/86829 (Missing sin(atan(x)) and cos(atan(x)) optimizations)
PR tree-optimization/86829 * match.pd (sin (atan (x))): New simplification rules. (cos (atan (x))): Likewise. * real.c (build_sinatan_real): New function. * real.h (build_sinatan_real): Prototype. PR tree-optimization/86829 * gcc.dg/sinatan-1.c: New test. * gcc.dg/sinatan-2.c: New test. * gcc.dg/sinatan-3.c: New test. From-SVN: r265064
Diffstat (limited to 'gcc/real.c')
-rw-r--r--gcc/real.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/real.c b/gcc/real.c
index f822ae8..51f8fd5 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5279,3 +5279,29 @@ HONOR_SIGN_DEPENDENT_ROUNDING (const_rtx x)
{
return HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (x));
}
+
+/* Fills r with the largest value such that 1 + r*r won't overflow.
+ This is used in both sin (atan (x)) and cos (atan(x)) optimizations. */
+
+void
+build_sinatan_real (REAL_VALUE_TYPE * r, tree type)
+{
+ REAL_VALUE_TYPE maxval;
+ mpfr_t mpfr_const1, mpfr_c, mpfr_maxval;
+ machine_mode mode = TYPE_MODE (type);
+ const struct real_format * fmt = REAL_MODE_FORMAT (mode);
+
+ real_maxval (&maxval, 0, mode);
+
+ mpfr_inits (mpfr_const1, mpfr_c, mpfr_maxval, NULL);
+
+ mpfr_from_real (mpfr_const1, &dconst1, GMP_RNDN);
+ mpfr_from_real (mpfr_maxval, &maxval, GMP_RNDN);
+
+ mpfr_sub (mpfr_c, mpfr_maxval, mpfr_const1, GMP_RNDN);
+ mpfr_sqrt (mpfr_c, mpfr_c, GMP_RNDZ);
+
+ real_from_mpfr (r, mpfr_c, fmt, GMP_RNDZ);
+
+ mpfr_clears (mpfr_const1, mpfr_c, mpfr_maxval, NULL);
+}