diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2018-10-11 21:06:12 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2018-10-11 15:06:12 -0600 |
commit | 121ef08b0b964ff4e7072a6af14613e68788abc4 (patch) | |
tree | e967a89e2270c12ad7a8fa8d6fbf6f4a32132efd /gcc/real.c | |
parent | ea010af6b4d780261b791999e43ba056edce2af0 (diff) | |
download | gcc-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.c | 26 |
1 files changed, 26 insertions, 0 deletions
@@ -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); +} |