Home | History | Annotate | Line # | Download | only in gcc
fold-const-call.cc revision 1.1
      1  1.1  mrg /* Constant folding for calls to built-in and internal functions.
      2  1.1  mrg    Copyright (C) 1988-2022 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      7  1.1  mrg the terms of the GNU General Public License as published by the Free
      8  1.1  mrg Software Foundation; either version 3, or (at your option) any later
      9  1.1  mrg version.
     10  1.1  mrg 
     11  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg for more details.
     15  1.1  mrg 
     16  1.1  mrg You should have received a copy of the GNU General Public License
     17  1.1  mrg along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg #include "config.h"
     21  1.1  mrg #include "system.h"
     22  1.1  mrg #include "coretypes.h"
     23  1.1  mrg #include "realmpfr.h"
     24  1.1  mrg #include "tree.h"
     25  1.1  mrg #include "stor-layout.h"
     26  1.1  mrg #include "options.h"
     27  1.1  mrg #include "fold-const.h"
     28  1.1  mrg #include "fold-const-call.h"
     29  1.1  mrg #include "case-cfn-macros.h"
     30  1.1  mrg #include "tm.h" /* For C[LT]Z_DEFINED_AT_ZERO.  */
     31  1.1  mrg #include "builtins.h"
     32  1.1  mrg #include "gimple-expr.h"
     33  1.1  mrg #include "tree-vector-builder.h"
     34  1.1  mrg 
     35  1.1  mrg /* Functions that test for certain constant types, abstracting away the
     36  1.1  mrg    decision about whether to check for overflow.  */
     37  1.1  mrg 
     38  1.1  mrg static inline bool
     39  1.1  mrg integer_cst_p (tree t)
     40  1.1  mrg {
     41  1.1  mrg   return TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t);
     42  1.1  mrg }
     43  1.1  mrg 
     44  1.1  mrg static inline bool
     45  1.1  mrg real_cst_p (tree t)
     46  1.1  mrg {
     47  1.1  mrg   return TREE_CODE (t) == REAL_CST && !TREE_OVERFLOW (t);
     48  1.1  mrg }
     49  1.1  mrg 
     50  1.1  mrg static inline bool
     51  1.1  mrg complex_cst_p (tree t)
     52  1.1  mrg {
     53  1.1  mrg   return TREE_CODE (t) == COMPLEX_CST;
     54  1.1  mrg }
     55  1.1  mrg 
     56  1.1  mrg /* Return true if ARG is a size_type_node constant.
     57  1.1  mrg    Store it in *SIZE_OUT if so.  */
     58  1.1  mrg 
     59  1.1  mrg static inline bool
     60  1.1  mrg size_t_cst_p (tree t, unsigned HOST_WIDE_INT *size_out)
     61  1.1  mrg {
     62  1.1  mrg   if (types_compatible_p (size_type_node, TREE_TYPE (t))
     63  1.1  mrg       && integer_cst_p (t)
     64  1.1  mrg       && tree_fits_uhwi_p (t))
     65  1.1  mrg     {
     66  1.1  mrg       *size_out = tree_to_uhwi (t);
     67  1.1  mrg       return true;
     68  1.1  mrg     }
     69  1.1  mrg   return false;
     70  1.1  mrg }
     71  1.1  mrg 
     72  1.1  mrg /* RES is the result of a comparison in which < 0 means "less", 0 means
     73  1.1  mrg    "equal" and > 0 means "more".  Canonicalize it to -1, 0 or 1 and
     74  1.1  mrg    return it in type TYPE.  */
     75  1.1  mrg 
     76  1.1  mrg tree
     77  1.1  mrg build_cmp_result (tree type, int res)
     78  1.1  mrg {
     79  1.1  mrg   return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0);
     80  1.1  mrg }
     81  1.1  mrg 
     82  1.1  mrg /* M is the result of trying to constant-fold an expression (starting
     83  1.1  mrg    with clear MPFR flags) and INEXACT says whether the result in M is
     84  1.1  mrg    exact or inexact.  Return true if M can be used as a constant-folded
     85  1.1  mrg    result in format FORMAT, storing the value in *RESULT if so.  */
     86  1.1  mrg 
     87  1.1  mrg static bool
     88  1.1  mrg do_mpfr_ckconv (real_value *result, mpfr_srcptr m, bool inexact,
     89  1.1  mrg 		const real_format *format)
     90  1.1  mrg {
     91  1.1  mrg   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
     92  1.1  mrg      overflow/underflow occurred.  If -frounding-math, proceed iff the
     93  1.1  mrg      result of calling FUNC was exact.  */
     94  1.1  mrg   if (!mpfr_number_p (m)
     95  1.1  mrg       || mpfr_overflow_p ()
     96  1.1  mrg       || mpfr_underflow_p ()
     97  1.1  mrg       || (flag_rounding_math && inexact))
     98  1.1  mrg     return false;
     99  1.1  mrg 
    100  1.1  mrg   REAL_VALUE_TYPE tmp;
    101  1.1  mrg   real_from_mpfr (&tmp, m, format, MPFR_RNDN);
    102  1.1  mrg 
    103  1.1  mrg   /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values.
    104  1.1  mrg      If the REAL_VALUE_TYPE is zero but the mpft_t is not, then we
    105  1.1  mrg      underflowed in the conversion.  */
    106  1.1  mrg   if (!real_isfinite (&tmp)
    107  1.1  mrg       || ((tmp.cl == rvc_zero) != (mpfr_zero_p (m) != 0)))
    108  1.1  mrg     return false;
    109  1.1  mrg 
    110  1.1  mrg   real_convert (result, format, &tmp);
    111  1.1  mrg   return real_identical (result, &tmp);
    112  1.1  mrg }
    113  1.1  mrg 
    114  1.1  mrg /* Try to evaluate:
    115  1.1  mrg 
    116  1.1  mrg       *RESULT = f (*ARG)
    117  1.1  mrg 
    118  1.1  mrg    in format FORMAT, given that FUNC is the MPFR implementation of f.
    119  1.1  mrg    Return true on success.  */
    120  1.1  mrg 
    121  1.1  mrg static bool
    122  1.1  mrg do_mpfr_arg1 (real_value *result,
    123  1.1  mrg 	      int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
    124  1.1  mrg 	      const real_value *arg, const real_format *format)
    125  1.1  mrg {
    126  1.1  mrg   /* To proceed, MPFR must exactly represent the target floating point
    127  1.1  mrg      format, which only happens when the target base equals two.  */
    128  1.1  mrg   if (format->b != 2 || !real_isfinite (arg))
    129  1.1  mrg     return false;
    130  1.1  mrg 
    131  1.1  mrg   int prec = format->p;
    132  1.1  mrg   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
    133  1.1  mrg   mpfr_t m;
    134  1.1  mrg 
    135  1.1  mrg   mpfr_init2 (m, prec);
    136  1.1  mrg   mpfr_from_real (m, arg, MPFR_RNDN);
    137  1.1  mrg   mpfr_clear_flags ();
    138  1.1  mrg   bool inexact = func (m, m, rnd);
    139  1.1  mrg   bool ok = do_mpfr_ckconv (result, m, inexact, format);
    140  1.1  mrg   mpfr_clear (m);
    141  1.1  mrg 
    142  1.1  mrg   return ok;
    143  1.1  mrg }
    144  1.1  mrg 
    145  1.1  mrg /* Try to evaluate:
    146  1.1  mrg 
    147  1.1  mrg       *RESULT_SIN = sin (*ARG);
    148  1.1  mrg       *RESULT_COS = cos (*ARG);
    149  1.1  mrg 
    150  1.1  mrg    for format FORMAT.  Return true on success.  */
    151  1.1  mrg 
    152  1.1  mrg static bool
    153  1.1  mrg do_mpfr_sincos (real_value *result_sin, real_value *result_cos,
    154  1.1  mrg 		const real_value *arg, const real_format *format)
    155  1.1  mrg {
    156  1.1  mrg   /* To proceed, MPFR must exactly represent the target floating point
    157  1.1  mrg      format, which only happens when the target base equals two.  */
    158  1.1  mrg   if (format->b != 2 || !real_isfinite (arg))
    159  1.1  mrg     return false;
    160  1.1  mrg 
    161  1.1  mrg   int prec = format->p;
    162  1.1  mrg   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
    163  1.1  mrg   mpfr_t m, ms, mc;
    164  1.1  mrg 
    165  1.1  mrg   mpfr_inits2 (prec, m, ms, mc, NULL);
    166  1.1  mrg   mpfr_from_real (m, arg, MPFR_RNDN);
    167  1.1  mrg   mpfr_clear_flags ();
    168  1.1  mrg   bool inexact = mpfr_sin_cos (ms, mc, m, rnd);
    169  1.1  mrg   bool ok = (do_mpfr_ckconv (result_sin, ms, inexact, format)
    170  1.1  mrg 	     && do_mpfr_ckconv (result_cos, mc, inexact, format));
    171  1.1  mrg   mpfr_clears (m, ms, mc, NULL);
    172  1.1  mrg 
    173  1.1  mrg   return ok;
    174  1.1  mrg }
    175  1.1  mrg 
    176  1.1  mrg /* Try to evaluate:
    177  1.1  mrg 
    178  1.1  mrg       *RESULT = f (*ARG0, *ARG1)
    179  1.1  mrg 
    180  1.1  mrg    in format FORMAT, given that FUNC is the MPFR implementation of f.
    181  1.1  mrg    Return true on success.  */
    182  1.1  mrg 
    183  1.1  mrg static bool
    184  1.1  mrg do_mpfr_arg2 (real_value *result,
    185  1.1  mrg 	      int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t),
    186  1.1  mrg 	      const real_value *arg0, const real_value *arg1,
    187  1.1  mrg 	      const real_format *format)
    188  1.1  mrg {
    189  1.1  mrg   /* To proceed, MPFR must exactly represent the target floating point
    190  1.1  mrg      format, which only happens when the target base equals two.  */
    191  1.1  mrg   if (format->b != 2 || !real_isfinite (arg0) || !real_isfinite (arg1))
    192  1.1  mrg     return false;
    193  1.1  mrg 
    194  1.1  mrg   int prec = format->p;
    195  1.1  mrg   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
    196  1.1  mrg   mpfr_t m0, m1;
    197  1.1  mrg 
    198  1.1  mrg   mpfr_inits2 (prec, m0, m1, NULL);
    199  1.1  mrg   mpfr_from_real (m0, arg0, MPFR_RNDN);
    200  1.1  mrg   mpfr_from_real (m1, arg1, MPFR_RNDN);
    201  1.1  mrg   mpfr_clear_flags ();
    202  1.1  mrg   bool inexact = func (m0, m0, m1, rnd);
    203  1.1  mrg   bool ok = do_mpfr_ckconv (result, m0, inexact, format);
    204  1.1  mrg   mpfr_clears (m0, m1, NULL);
    205  1.1  mrg 
    206  1.1  mrg   return ok;
    207  1.1  mrg }
    208  1.1  mrg 
    209  1.1  mrg /* Try to evaluate:
    210  1.1  mrg 
    211  1.1  mrg       *RESULT = f (ARG0, *ARG1)
    212  1.1  mrg 
    213  1.1  mrg    in format FORMAT, given that FUNC is the MPFR implementation of f.
    214  1.1  mrg    Return true on success.  */
    215  1.1  mrg 
    216  1.1  mrg static bool
    217  1.1  mrg do_mpfr_arg2 (real_value *result,
    218  1.1  mrg 	      int (*func) (mpfr_ptr, long, mpfr_srcptr, mpfr_rnd_t),
    219  1.1  mrg 	      const wide_int_ref &arg0, const real_value *arg1,
    220  1.1  mrg 	      const real_format *format)
    221  1.1  mrg {
    222  1.1  mrg   if (format->b != 2 || !real_isfinite (arg1))
    223  1.1  mrg     return false;
    224  1.1  mrg 
    225  1.1  mrg   int prec = format->p;
    226  1.1  mrg   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
    227  1.1  mrg   mpfr_t m;
    228  1.1  mrg 
    229  1.1  mrg   mpfr_init2 (m, prec);
    230  1.1  mrg   mpfr_from_real (m, arg1, MPFR_RNDN);
    231  1.1  mrg   mpfr_clear_flags ();
    232  1.1  mrg   bool inexact = func (m, arg0.to_shwi (), m, rnd);
    233  1.1  mrg   bool ok = do_mpfr_ckconv (result, m, inexact, format);
    234  1.1  mrg   mpfr_clear (m);
    235  1.1  mrg 
    236  1.1  mrg   return ok;
    237  1.1  mrg }
    238  1.1  mrg 
    239  1.1  mrg /* Try to evaluate:
    240  1.1  mrg 
    241  1.1  mrg       *RESULT = f (*ARG0, *ARG1, *ARG2)
    242  1.1  mrg 
    243  1.1  mrg    in format FORMAT, given that FUNC is the MPFR implementation of f.
    244  1.1  mrg    Return true on success.  */
    245  1.1  mrg 
    246  1.1  mrg static bool
    247  1.1  mrg do_mpfr_arg3 (real_value *result,
    248  1.1  mrg 	      int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_srcptr,
    249  1.1  mrg 			   mpfr_srcptr, mpfr_rnd_t),
    250  1.1  mrg 	      const real_value *arg0, const real_value *arg1,
    251  1.1  mrg 	      const real_value *arg2, const real_format *format)
    252  1.1  mrg {
    253  1.1  mrg   /* To proceed, MPFR must exactly represent the target floating point
    254  1.1  mrg      format, which only happens when the target base equals two.  */
    255  1.1  mrg   if (format->b != 2
    256  1.1  mrg       || !real_isfinite (arg0)
    257  1.1  mrg       || !real_isfinite (arg1)
    258  1.1  mrg       || !real_isfinite (arg2))
    259  1.1  mrg     return false;
    260  1.1  mrg 
    261  1.1  mrg   int prec = format->p;
    262  1.1  mrg   mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
    263  1.1  mrg   mpfr_t m0, m1, m2;
    264  1.1  mrg 
    265  1.1  mrg   mpfr_inits2 (prec, m0, m1, m2, NULL);
    266  1.1  mrg   mpfr_from_real (m0, arg0, MPFR_RNDN);
    267  1.1  mrg   mpfr_from_real (m1, arg1, MPFR_RNDN);
    268  1.1  mrg   mpfr_from_real (m2, arg2, MPFR_RNDN);
    269  1.1  mrg   mpfr_clear_flags ();
    270  1.1  mrg   bool inexact = func (m0, m0, m1, m2, rnd);
    271  1.1  mrg   bool ok = do_mpfr_ckconv (result, m0, inexact, format);
    272  1.1  mrg   mpfr_clears (m0, m1, m2, NULL);
    273  1.1  mrg 
    274  1.1  mrg   return ok;
    275  1.1  mrg }
    276  1.1  mrg 
    277  1.1  mrg /* M is the result of trying to constant-fold an expression (starting
    278  1.1  mrg    with clear MPFR flags) and INEXACT says whether the result in M is
    279  1.1  mrg    exact or inexact.  Return true if M can be used as a constant-folded
    280  1.1  mrg    result in which the real and imaginary parts have format FORMAT.
    281  1.1  mrg    Store those parts in *RESULT_REAL and *RESULT_IMAG if so.  */
    282  1.1  mrg 
    283  1.1  mrg static bool
    284  1.1  mrg do_mpc_ckconv (real_value *result_real, real_value *result_imag,
    285  1.1  mrg 	       mpc_srcptr m, bool inexact, const real_format *format)
    286  1.1  mrg {
    287  1.1  mrg   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
    288  1.1  mrg      overflow/underflow occurred.  If -frounding-math, proceed iff the
    289  1.1  mrg      result of calling FUNC was exact.  */
    290  1.1  mrg   if (!mpfr_number_p (mpc_realref (m))
    291  1.1  mrg       || !mpfr_number_p (mpc_imagref (m))
    292  1.1  mrg       || mpfr_overflow_p ()
    293  1.1  mrg       || mpfr_underflow_p ()
    294  1.1  mrg       || (flag_rounding_math && inexact))
    295  1.1  mrg     return false;
    296  1.1  mrg 
    297  1.1  mrg   REAL_VALUE_TYPE tmp_real, tmp_imag;
    298  1.1  mrg   real_from_mpfr (&tmp_real, mpc_realref (m), format, MPFR_RNDN);
    299  1.1  mrg   real_from_mpfr (&tmp_imag, mpc_imagref (m), format, MPFR_RNDN);
    300  1.1  mrg 
    301  1.1  mrg   /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values.
    302  1.1  mrg      If the REAL_VALUE_TYPE is zero but the mpft_t is not, then we
    303  1.1  mrg      underflowed in the conversion.  */
    304  1.1  mrg   if (!real_isfinite (&tmp_real)
    305  1.1  mrg       || !real_isfinite (&tmp_imag)
    306  1.1  mrg       || (tmp_real.cl == rvc_zero) != (mpfr_zero_p (mpc_realref (m)) != 0)
    307  1.1  mrg       || (tmp_imag.cl == rvc_zero) != (mpfr_zero_p (mpc_imagref (m)) != 0))
    308  1.1  mrg     return false;
    309  1.1  mrg 
    310  1.1  mrg   real_convert (result_real, format, &tmp_real);
    311  1.1  mrg   real_convert (result_imag, format, &tmp_imag);
    312  1.1  mrg 
    313  1.1  mrg   return (real_identical (result_real, &tmp_real)
    314  1.1  mrg 	  && real_identical (result_imag, &tmp_imag));
    315  1.1  mrg }
    316  1.1  mrg 
    317  1.1  mrg /* Try to evaluate:
    318  1.1  mrg 
    319  1.1  mrg       RESULT = f (ARG)
    320  1.1  mrg 
    321  1.1  mrg    in format FORMAT, given that FUNC is the mpc implementation of f.
    322  1.1  mrg    Return true on success.  Both RESULT and ARG are represented as
    323  1.1  mrg    real and imaginary pairs.  */
    324  1.1  mrg 
    325  1.1  mrg static bool
    326  1.1  mrg do_mpc_arg1 (real_value *result_real, real_value *result_imag,
    327  1.1  mrg 	     int (*func) (mpc_ptr, mpc_srcptr, mpc_rnd_t),
    328  1.1  mrg 	     const real_value *arg_real, const real_value *arg_imag,
    329  1.1  mrg 	     const real_format *format)
    330  1.1  mrg {
    331  1.1  mrg   /* To proceed, MPFR must exactly represent the target floating point
    332  1.1  mrg      format, which only happens when the target base equals two.  */
    333  1.1  mrg   if (format->b != 2
    334  1.1  mrg       || !real_isfinite (arg_real)
    335  1.1  mrg       || !real_isfinite (arg_imag))
    336  1.1  mrg     return false;
    337  1.1  mrg 
    338  1.1  mrg   int prec = format->p;
    339  1.1  mrg   mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
    340  1.1  mrg   mpc_t m;
    341  1.1  mrg 
    342  1.1  mrg   mpc_init2 (m, prec);
    343  1.1  mrg   mpfr_from_real (mpc_realref (m), arg_real, MPFR_RNDN);
    344  1.1  mrg   mpfr_from_real (mpc_imagref (m), arg_imag, MPFR_RNDN);
    345  1.1  mrg   mpfr_clear_flags ();
    346  1.1  mrg   bool inexact = func (m, m, crnd);
    347  1.1  mrg   bool ok = do_mpc_ckconv (result_real, result_imag, m, inexact, format);
    348  1.1  mrg   mpc_clear (m);
    349  1.1  mrg 
    350  1.1  mrg   return ok;
    351  1.1  mrg }
    352  1.1  mrg 
    353  1.1  mrg /* Try to evaluate:
    354  1.1  mrg 
    355  1.1  mrg       RESULT = f (ARG0, ARG1)
    356  1.1  mrg 
    357  1.1  mrg    in format FORMAT, given that FUNC is the mpc implementation of f.
    358  1.1  mrg    Return true on success.  RESULT, ARG0 and ARG1 are represented as
    359  1.1  mrg    real and imaginary pairs.  */
    360  1.1  mrg 
    361  1.1  mrg static bool
    362  1.1  mrg do_mpc_arg2 (real_value *result_real, real_value *result_imag,
    363  1.1  mrg 	     int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t),
    364  1.1  mrg 	     const real_value *arg0_real, const real_value *arg0_imag,
    365  1.1  mrg 	     const real_value *arg1_real, const real_value *arg1_imag,
    366  1.1  mrg 	     const real_format *format)
    367  1.1  mrg {
    368  1.1  mrg   if (!real_isfinite (arg0_real)
    369  1.1  mrg       || !real_isfinite (arg0_imag)
    370  1.1  mrg       || !real_isfinite (arg1_real)
    371  1.1  mrg       || !real_isfinite (arg1_imag))
    372  1.1  mrg     return false;
    373  1.1  mrg 
    374  1.1  mrg   int prec = format->p;
    375  1.1  mrg   mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
    376  1.1  mrg   mpc_t m0, m1;
    377  1.1  mrg 
    378  1.1  mrg   mpc_init2 (m0, prec);
    379  1.1  mrg   mpc_init2 (m1, prec);
    380  1.1  mrg   mpfr_from_real (mpc_realref (m0), arg0_real, MPFR_RNDN);
    381  1.1  mrg   mpfr_from_real (mpc_imagref (m0), arg0_imag, MPFR_RNDN);
    382  1.1  mrg   mpfr_from_real (mpc_realref (m1), arg1_real, MPFR_RNDN);
    383  1.1  mrg   mpfr_from_real (mpc_imagref (m1), arg1_imag, MPFR_RNDN);
    384  1.1  mrg   mpfr_clear_flags ();
    385  1.1  mrg   bool inexact = func (m0, m0, m1, crnd);
    386  1.1  mrg   bool ok = do_mpc_ckconv (result_real, result_imag, m0, inexact, format);
    387  1.1  mrg   mpc_clear (m0);
    388  1.1  mrg   mpc_clear (m1);
    389  1.1  mrg 
    390  1.1  mrg   return ok;
    391  1.1  mrg }
    392  1.1  mrg 
    393  1.1  mrg /* Try to evaluate:
    394  1.1  mrg 
    395  1.1  mrg       *RESULT = logb (*ARG)
    396  1.1  mrg 
    397  1.1  mrg    in format FORMAT.  Return true on success.  */
    398  1.1  mrg 
    399  1.1  mrg static bool
    400  1.1  mrg fold_const_logb (real_value *result, const real_value *arg,
    401  1.1  mrg 		 const real_format *format)
    402  1.1  mrg {
    403  1.1  mrg   switch (arg->cl)
    404  1.1  mrg     {
    405  1.1  mrg     case rvc_nan:
    406  1.1  mrg       /* If arg is +-NaN, then return it.  */
    407  1.1  mrg       *result = *arg;
    408  1.1  mrg       return true;
    409  1.1  mrg 
    410  1.1  mrg     case rvc_inf:
    411  1.1  mrg       /* If arg is +-Inf, then return +Inf.  */
    412  1.1  mrg       *result = *arg;
    413  1.1  mrg       result->sign = 0;
    414  1.1  mrg       return true;
    415  1.1  mrg 
    416  1.1  mrg     case rvc_zero:
    417  1.1  mrg       /* Zero may set errno and/or raise an exception.  */
    418  1.1  mrg       return false;
    419  1.1  mrg 
    420  1.1  mrg     case rvc_normal:
    421  1.1  mrg       /* For normal numbers, proceed iff radix == 2.  In GCC,
    422  1.1  mrg 	 normalized significands are in the range [0.5, 1.0).  We
    423  1.1  mrg 	 want the exponent as if they were [1.0, 2.0) so get the
    424  1.1  mrg 	 exponent and subtract 1.  */
    425  1.1  mrg       if (format->b == 2)
    426  1.1  mrg 	{
    427  1.1  mrg 	  real_from_integer (result, format, REAL_EXP (arg) - 1, SIGNED);
    428  1.1  mrg 	  return true;
    429  1.1  mrg 	}
    430  1.1  mrg       return false;
    431  1.1  mrg     }
    432  1.1  mrg }
    433  1.1  mrg 
    434  1.1  mrg /* Try to evaluate:
    435  1.1  mrg 
    436  1.1  mrg       *RESULT = significand (*ARG)
    437  1.1  mrg 
    438  1.1  mrg    in format FORMAT.  Return true on success.  */
    439  1.1  mrg 
    440  1.1  mrg static bool
    441  1.1  mrg fold_const_significand (real_value *result, const real_value *arg,
    442  1.1  mrg 			const real_format *format)
    443  1.1  mrg {
    444  1.1  mrg   switch (arg->cl)
    445  1.1  mrg     {
    446  1.1  mrg     case rvc_zero:
    447  1.1  mrg     case rvc_nan:
    448  1.1  mrg     case rvc_inf:
    449  1.1  mrg       /* If arg is +-0, +-Inf or +-NaN, then return it.  */
    450  1.1  mrg       *result = *arg;
    451  1.1  mrg       return true;
    452  1.1  mrg 
    453  1.1  mrg     case rvc_normal:
    454  1.1  mrg       /* For normal numbers, proceed iff radix == 2.  */
    455  1.1  mrg       if (format->b == 2)
    456  1.1  mrg 	{
    457  1.1  mrg 	  *result = *arg;
    458  1.1  mrg 	  /* In GCC, normalized significands are in the range [0.5, 1.0).
    459  1.1  mrg 	     We want them to be [1.0, 2.0) so set the exponent to 1.  */
    460  1.1  mrg 	  SET_REAL_EXP (result, 1);
    461  1.1  mrg 	  return true;
    462  1.1  mrg 	}
    463  1.1  mrg       return false;
    464  1.1  mrg     }
    465  1.1  mrg }
    466  1.1  mrg 
    467  1.1  mrg /* Try to evaluate:
    468  1.1  mrg 
    469  1.1  mrg       *RESULT = f (*ARG)
    470  1.1  mrg 
    471  1.1  mrg    where FORMAT is the format of *ARG and PRECISION is the number of
    472  1.1  mrg    significant bits in the result.  Return true on success.  */
    473  1.1  mrg 
    474  1.1  mrg static bool
    475  1.1  mrg fold_const_conversion (wide_int *result,
    476  1.1  mrg 		       void (*fn) (real_value *, format_helper,
    477  1.1  mrg 				   const real_value *),
    478  1.1  mrg 		       const real_value *arg, unsigned int precision,
    479  1.1  mrg 		       const real_format *format)
    480  1.1  mrg {
    481  1.1  mrg   if (!real_isfinite (arg))
    482  1.1  mrg     return false;
    483  1.1  mrg 
    484  1.1  mrg   real_value rounded;
    485  1.1  mrg   fn (&rounded, format, arg);
    486  1.1  mrg 
    487  1.1  mrg   bool fail = false;
    488  1.1  mrg   *result = real_to_integer (&rounded, &fail, precision);
    489  1.1  mrg   return !fail;
    490  1.1  mrg }
    491  1.1  mrg 
    492  1.1  mrg /* Try to evaluate:
    493  1.1  mrg 
    494  1.1  mrg       *RESULT = pow (*ARG0, *ARG1)
    495  1.1  mrg 
    496  1.1  mrg    in format FORMAT.  Return true on success.  */
    497  1.1  mrg 
    498  1.1  mrg static bool
    499  1.1  mrg fold_const_pow (real_value *result, const real_value *arg0,
    500  1.1  mrg 		const real_value *arg1, const real_format *format)
    501  1.1  mrg {
    502  1.1  mrg   if (do_mpfr_arg2 (result, mpfr_pow, arg0, arg1, format))
    503  1.1  mrg     return true;
    504  1.1  mrg 
    505  1.1  mrg   /* Check for an integer exponent.  */
    506  1.1  mrg   REAL_VALUE_TYPE cint1;
    507  1.1  mrg   HOST_WIDE_INT n1 = real_to_integer (arg1);
    508  1.1  mrg   real_from_integer (&cint1, VOIDmode, n1, SIGNED);
    509  1.1  mrg   /* Attempt to evaluate pow at compile-time, unless this should
    510  1.1  mrg      raise an exception.  */
    511  1.1  mrg   if (real_identical (arg1, &cint1)
    512  1.1  mrg       && (n1 > 0
    513  1.1  mrg 	  || (!flag_trapping_math && !flag_errno_math)
    514  1.1  mrg 	  || !real_equal (arg0, &dconst0)))
    515  1.1  mrg     {
    516  1.1  mrg       bool inexact = real_powi (result, format, arg0, n1);
    517  1.1  mrg       /* Avoid the folding if flag_signaling_nans is on.  */
    518  1.1  mrg       if (flag_unsafe_math_optimizations
    519  1.1  mrg 	  || (!inexact
    520  1.1  mrg 	      && !(flag_signaling_nans
    521  1.1  mrg 	           && REAL_VALUE_ISSIGNALING_NAN (*arg0))))
    522  1.1  mrg 	return true;
    523  1.1  mrg     }
    524  1.1  mrg 
    525  1.1  mrg   return false;
    526  1.1  mrg }
    527  1.1  mrg 
    528  1.1  mrg /* Try to evaluate:
    529  1.1  mrg 
    530  1.1  mrg       *RESULT = nextafter (*ARG0, *ARG1)
    531  1.1  mrg 
    532  1.1  mrg    or
    533  1.1  mrg 
    534  1.1  mrg       *RESULT = nexttoward (*ARG0, *ARG1)
    535  1.1  mrg 
    536  1.1  mrg    in format FORMAT.  Return true on success.  */
    537  1.1  mrg 
    538  1.1  mrg static bool
    539  1.1  mrg fold_const_nextafter (real_value *result, const real_value *arg0,
    540  1.1  mrg 		      const real_value *arg1, const real_format *format)
    541  1.1  mrg {
    542  1.1  mrg   if (REAL_VALUE_ISSIGNALING_NAN (*arg0)
    543  1.1  mrg       || REAL_VALUE_ISSIGNALING_NAN (*arg1))
    544  1.1  mrg     return false;
    545  1.1  mrg 
    546  1.1  mrg   /* Don't handle composite modes, nor decimal, nor modes without
    547  1.1  mrg      inf or denorm at least for now.  */
    548  1.1  mrg   if (format->pnan < format->p
    549  1.1  mrg       || format->b == 10
    550  1.1  mrg       || !format->has_inf
    551  1.1  mrg       || !format->has_denorm)
    552  1.1  mrg     return false;
    553  1.1  mrg 
    554  1.1  mrg   if (real_nextafter (result, format, arg0, arg1)
    555  1.1  mrg       /* If raising underflow or overflow and setting errno to ERANGE,
    556  1.1  mrg 	 fail if we care about those side-effects.  */
    557  1.1  mrg       && (flag_trapping_math || flag_errno_math))
    558  1.1  mrg     return false;
    559  1.1  mrg   /* Similarly for nextafter (0, 1) raising underflow.  */
    560  1.1  mrg   else if (flag_trapping_math
    561  1.1  mrg 	   && arg0->cl == rvc_zero
    562  1.1  mrg 	   && result->cl != rvc_zero)
    563  1.1  mrg     return false;
    564  1.1  mrg 
    565  1.1  mrg   real_convert (result, format, result);
    566  1.1  mrg 
    567  1.1  mrg   return true;
    568  1.1  mrg }
    569  1.1  mrg 
    570  1.1  mrg /* Try to evaluate:
    571  1.1  mrg 
    572  1.1  mrg       *RESULT = ldexp (*ARG0, ARG1)
    573  1.1  mrg 
    574  1.1  mrg    in format FORMAT.  Return true on success.  */
    575  1.1  mrg 
    576  1.1  mrg static bool
    577  1.1  mrg fold_const_builtin_load_exponent (real_value *result, const real_value *arg0,
    578  1.1  mrg 				  const wide_int_ref &arg1,
    579  1.1  mrg 				  const real_format *format)
    580  1.1  mrg {
    581  1.1  mrg   /* Bound the maximum adjustment to twice the range of the
    582  1.1  mrg      mode's valid exponents.  Use abs to ensure the range is
    583  1.1  mrg      positive as a sanity check.  */
    584  1.1  mrg   int max_exp_adj = 2 * labs (format->emax - format->emin);
    585  1.1  mrg 
    586  1.1  mrg   /* The requested adjustment must be inside this range.  This
    587  1.1  mrg      is a preliminary cap to avoid things like overflow, we
    588  1.1  mrg      may still fail to compute the result for other reasons.  */
    589  1.1  mrg   if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj))
    590  1.1  mrg     return false;
    591  1.1  mrg 
    592  1.1  mrg   /* Don't perform operation if we honor signaling NaNs and
    593  1.1  mrg      operand is a signaling NaN.  */
    594  1.1  mrg   if (!flag_unsafe_math_optimizations
    595  1.1  mrg       && flag_signaling_nans
    596  1.1  mrg       && REAL_VALUE_ISSIGNALING_NAN (*arg0))
    597  1.1  mrg     return false;
    598  1.1  mrg 
    599  1.1  mrg   REAL_VALUE_TYPE initial_result;
    600  1.1  mrg   real_ldexp (&initial_result, arg0, arg1.to_shwi ());
    601  1.1  mrg 
    602  1.1  mrg   /* Ensure we didn't overflow.  */
    603  1.1  mrg   if (real_isinf (&initial_result))
    604  1.1  mrg     return false;
    605  1.1  mrg 
    606  1.1  mrg   /* Only proceed if the target mode can hold the
    607  1.1  mrg      resulting value.  */
    608  1.1  mrg   *result = real_value_truncate (format, initial_result);
    609  1.1  mrg   return real_equal (&initial_result, result);
    610  1.1  mrg }
    611  1.1  mrg 
    612  1.1  mrg /* Fold a call to __builtin_nan or __builtin_nans with argument ARG and
    613  1.1  mrg    return type TYPE.  QUIET is true if a quiet rather than signalling
    614  1.1  mrg    NaN is required.  */
    615  1.1  mrg 
    616  1.1  mrg static tree
    617  1.1  mrg fold_const_builtin_nan (tree type, tree arg, bool quiet)
    618  1.1  mrg {
    619  1.1  mrg   REAL_VALUE_TYPE real;
    620  1.1  mrg   const char *str = c_getstr (arg);
    621  1.1  mrg   if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
    622  1.1  mrg     return build_real (type, real);
    623  1.1  mrg   return NULL_TREE;
    624  1.1  mrg }
    625  1.1  mrg 
    626  1.1  mrg /* Fold a call to IFN_REDUC_<CODE> (ARG), returning a value of type TYPE.  */
    627  1.1  mrg 
    628  1.1  mrg static tree
    629  1.1  mrg fold_const_reduction (tree type, tree arg, tree_code code)
    630  1.1  mrg {
    631  1.1  mrg   unsigned HOST_WIDE_INT nelts;
    632  1.1  mrg   if (TREE_CODE (arg) != VECTOR_CST
    633  1.1  mrg       || !VECTOR_CST_NELTS (arg).is_constant (&nelts))
    634  1.1  mrg     return NULL_TREE;
    635  1.1  mrg 
    636  1.1  mrg   tree res = VECTOR_CST_ELT (arg, 0);
    637  1.1  mrg   for (unsigned HOST_WIDE_INT i = 1; i < nelts; i++)
    638  1.1  mrg     {
    639  1.1  mrg       res = const_binop (code, type, res, VECTOR_CST_ELT (arg, i));
    640  1.1  mrg       if (res == NULL_TREE || !CONSTANT_CLASS_P (res))
    641  1.1  mrg 	return NULL_TREE;
    642  1.1  mrg     }
    643  1.1  mrg   return res;
    644  1.1  mrg }
    645  1.1  mrg 
    646  1.1  mrg /* Fold a call to IFN_VEC_CONVERT (ARG) returning TYPE.  */
    647  1.1  mrg 
    648  1.1  mrg static tree
    649  1.1  mrg fold_const_vec_convert (tree ret_type, tree arg)
    650  1.1  mrg {
    651  1.1  mrg   enum tree_code code = NOP_EXPR;
    652  1.1  mrg   tree arg_type = TREE_TYPE (arg);
    653  1.1  mrg   if (TREE_CODE (arg) != VECTOR_CST)
    654  1.1  mrg     return NULL_TREE;
    655  1.1  mrg 
    656  1.1  mrg   gcc_checking_assert (VECTOR_TYPE_P (ret_type) && VECTOR_TYPE_P (arg_type));
    657  1.1  mrg 
    658  1.1  mrg   if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
    659  1.1  mrg       && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type)))
    660  1.1  mrg     code = FIX_TRUNC_EXPR;
    661  1.1  mrg   else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
    662  1.1  mrg 	   && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type)))
    663  1.1  mrg     code = FLOAT_EXPR;
    664  1.1  mrg 
    665  1.1  mrg   /* We can't handle steps directly when extending, since the
    666  1.1  mrg      values need to wrap at the original precision first.  */
    667  1.1  mrg   bool step_ok_p
    668  1.1  mrg     = (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
    669  1.1  mrg        && INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
    670  1.1  mrg        && (TYPE_PRECISION (TREE_TYPE (ret_type))
    671  1.1  mrg 	   <= TYPE_PRECISION (TREE_TYPE (arg_type))));
    672  1.1  mrg   tree_vector_builder elts;
    673  1.1  mrg   if (!elts.new_unary_operation (ret_type, arg, step_ok_p))
    674  1.1  mrg     return NULL_TREE;
    675  1.1  mrg 
    676  1.1  mrg   unsigned int count = elts.encoded_nelts ();
    677  1.1  mrg   for (unsigned int i = 0; i < count; ++i)
    678  1.1  mrg     {
    679  1.1  mrg       tree elt = fold_unary (code, TREE_TYPE (ret_type),
    680  1.1  mrg 			     VECTOR_CST_ELT (arg, i));
    681  1.1  mrg       if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt))
    682  1.1  mrg 	return NULL_TREE;
    683  1.1  mrg       elts.quick_push (elt);
    684  1.1  mrg     }
    685  1.1  mrg 
    686  1.1  mrg   return elts.build ();
    687  1.1  mrg }
    688  1.1  mrg 
    689  1.1  mrg /* Try to evaluate:
    690  1.1  mrg 
    691  1.1  mrg       IFN_WHILE_ULT (ARG0, ARG1, (TYPE) { ... })
    692  1.1  mrg 
    693  1.1  mrg    Return the value on success and null on failure.  */
    694  1.1  mrg 
    695  1.1  mrg static tree
    696  1.1  mrg fold_while_ult (tree type, poly_uint64 arg0, poly_uint64 arg1)
    697  1.1  mrg {
    698  1.1  mrg   if (known_ge (arg0, arg1))
    699  1.1  mrg     return build_zero_cst (type);
    700  1.1  mrg 
    701  1.1  mrg   if (maybe_ge (arg0, arg1))
    702  1.1  mrg     return NULL_TREE;
    703  1.1  mrg 
    704  1.1  mrg   poly_uint64 diff = arg1 - arg0;
    705  1.1  mrg   poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
    706  1.1  mrg   if (known_ge (diff, nelts))
    707  1.1  mrg     return build_all_ones_cst (type);
    708  1.1  mrg 
    709  1.1  mrg   unsigned HOST_WIDE_INT const_diff;
    710  1.1  mrg   if (known_le (diff, nelts) && diff.is_constant (&const_diff))
    711  1.1  mrg     {
    712  1.1  mrg       tree minus_one = build_minus_one_cst (TREE_TYPE (type));
    713  1.1  mrg       tree zero = build_zero_cst (TREE_TYPE (type));
    714  1.1  mrg       return build_vector_a_then_b (type, const_diff, minus_one, zero);
    715  1.1  mrg     }
    716  1.1  mrg   return NULL_TREE;
    717  1.1  mrg }
    718  1.1  mrg 
    719  1.1  mrg /* Try to evaluate:
    720  1.1  mrg 
    721  1.1  mrg       *RESULT = FN (*ARG)
    722  1.1  mrg 
    723  1.1  mrg    in format FORMAT.  Return true on success.  */
    724  1.1  mrg 
    725  1.1  mrg static bool
    726  1.1  mrg fold_const_call_ss (real_value *result, combined_fn fn,
    727  1.1  mrg 		    const real_value *arg, const real_format *format)
    728  1.1  mrg {
    729  1.1  mrg   switch (fn)
    730  1.1  mrg     {
    731  1.1  mrg     CASE_CFN_SQRT:
    732  1.1  mrg     CASE_CFN_SQRT_FN:
    733  1.1  mrg       return (real_compare (GE_EXPR, arg, &dconst0)
    734  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
    735  1.1  mrg 
    736  1.1  mrg     CASE_CFN_CBRT:
    737  1.1  mrg       return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
    738  1.1  mrg 
    739  1.1  mrg     CASE_CFN_ASIN:
    740  1.1  mrg       return (real_compare (GE_EXPR, arg, &dconstm1)
    741  1.1  mrg 	      && real_compare (LE_EXPR, arg, &dconst1)
    742  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_asin, arg, format));
    743  1.1  mrg 
    744  1.1  mrg     CASE_CFN_ACOS:
    745  1.1  mrg       return (real_compare (GE_EXPR, arg, &dconstm1)
    746  1.1  mrg 	      && real_compare (LE_EXPR, arg, &dconst1)
    747  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_acos, arg, format));
    748  1.1  mrg 
    749  1.1  mrg     CASE_CFN_ATAN:
    750  1.1  mrg       return do_mpfr_arg1 (result, mpfr_atan, arg, format);
    751  1.1  mrg 
    752  1.1  mrg     CASE_CFN_ASINH:
    753  1.1  mrg       return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
    754  1.1  mrg 
    755  1.1  mrg     CASE_CFN_ACOSH:
    756  1.1  mrg       return (real_compare (GE_EXPR, arg, &dconst1)
    757  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
    758  1.1  mrg 
    759  1.1  mrg     CASE_CFN_ATANH:
    760  1.1  mrg       return (real_compare (GE_EXPR, arg, &dconstm1)
    761  1.1  mrg 	      && real_compare (LE_EXPR, arg, &dconst1)
    762  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_atanh, arg, format));
    763  1.1  mrg 
    764  1.1  mrg     CASE_CFN_SIN:
    765  1.1  mrg       return do_mpfr_arg1 (result, mpfr_sin, arg, format);
    766  1.1  mrg 
    767  1.1  mrg     CASE_CFN_COS:
    768  1.1  mrg       return do_mpfr_arg1 (result, mpfr_cos, arg, format);
    769  1.1  mrg 
    770  1.1  mrg     CASE_CFN_TAN:
    771  1.1  mrg       return do_mpfr_arg1 (result, mpfr_tan, arg, format);
    772  1.1  mrg 
    773  1.1  mrg     CASE_CFN_SINH:
    774  1.1  mrg       return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
    775  1.1  mrg 
    776  1.1  mrg     CASE_CFN_COSH:
    777  1.1  mrg       return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
    778  1.1  mrg 
    779  1.1  mrg     CASE_CFN_TANH:
    780  1.1  mrg       return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
    781  1.1  mrg 
    782  1.1  mrg     CASE_CFN_ERF:
    783  1.1  mrg       return do_mpfr_arg1 (result, mpfr_erf, arg, format);
    784  1.1  mrg 
    785  1.1  mrg     CASE_CFN_ERFC:
    786  1.1  mrg       return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
    787  1.1  mrg 
    788  1.1  mrg     CASE_CFN_TGAMMA:
    789  1.1  mrg       return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
    790  1.1  mrg 
    791  1.1  mrg     CASE_CFN_EXP:
    792  1.1  mrg       return do_mpfr_arg1 (result, mpfr_exp, arg, format);
    793  1.1  mrg 
    794  1.1  mrg     CASE_CFN_EXP2:
    795  1.1  mrg       return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
    796  1.1  mrg 
    797  1.1  mrg     CASE_CFN_EXP10:
    798  1.1  mrg     CASE_CFN_POW10:
    799  1.1  mrg       return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
    800  1.1  mrg 
    801  1.1  mrg     CASE_CFN_EXPM1:
    802  1.1  mrg       return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
    803  1.1  mrg 
    804  1.1  mrg     CASE_CFN_LOG:
    805  1.1  mrg       return (real_compare (GT_EXPR, arg, &dconst0)
    806  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_log, arg, format));
    807  1.1  mrg 
    808  1.1  mrg     CASE_CFN_LOG2:
    809  1.1  mrg       return (real_compare (GT_EXPR, arg, &dconst0)
    810  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_log2, arg, format));
    811  1.1  mrg 
    812  1.1  mrg     CASE_CFN_LOG10:
    813  1.1  mrg       return (real_compare (GT_EXPR, arg, &dconst0)
    814  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_log10, arg, format));
    815  1.1  mrg 
    816  1.1  mrg     CASE_CFN_LOG1P:
    817  1.1  mrg       return (real_compare (GT_EXPR, arg, &dconstm1)
    818  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
    819  1.1  mrg 
    820  1.1  mrg     CASE_CFN_J0:
    821  1.1  mrg       return do_mpfr_arg1 (result, mpfr_j0, arg, format);
    822  1.1  mrg 
    823  1.1  mrg     CASE_CFN_J1:
    824  1.1  mrg       return do_mpfr_arg1 (result, mpfr_j1, arg, format);
    825  1.1  mrg 
    826  1.1  mrg     CASE_CFN_Y0:
    827  1.1  mrg       return (real_compare (GT_EXPR, arg, &dconst0)
    828  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_y0, arg, format));
    829  1.1  mrg 
    830  1.1  mrg     CASE_CFN_Y1:
    831  1.1  mrg       return (real_compare (GT_EXPR, arg, &dconst0)
    832  1.1  mrg 	      && do_mpfr_arg1 (result, mpfr_y1, arg, format));
    833  1.1  mrg 
    834  1.1  mrg     CASE_CFN_FLOOR:
    835  1.1  mrg     CASE_CFN_FLOOR_FN:
    836  1.1  mrg       if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
    837  1.1  mrg 	{
    838  1.1  mrg 	  real_floor (result, format, arg);
    839  1.1  mrg 	  return true;
    840  1.1  mrg 	}
    841  1.1  mrg       return false;
    842  1.1  mrg 
    843  1.1  mrg     CASE_CFN_CEIL:
    844  1.1  mrg     CASE_CFN_CEIL_FN:
    845  1.1  mrg       if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
    846  1.1  mrg 	{
    847  1.1  mrg 	  real_ceil (result, format, arg);
    848  1.1  mrg 	  return true;
    849  1.1  mrg 	}
    850  1.1  mrg       return false;
    851  1.1  mrg 
    852  1.1  mrg     CASE_CFN_TRUNC:
    853  1.1  mrg     CASE_CFN_TRUNC_FN:
    854  1.1  mrg       if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
    855  1.1  mrg 	{
    856  1.1  mrg 	  real_trunc (result, format, arg);
    857  1.1  mrg 	  return true;
    858  1.1  mrg 	}
    859  1.1  mrg       return false;
    860  1.1  mrg 
    861  1.1  mrg     CASE_CFN_ROUND:
    862  1.1  mrg     CASE_CFN_ROUND_FN:
    863  1.1  mrg       if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
    864  1.1  mrg 	{
    865  1.1  mrg 	  real_round (result, format, arg);
    866  1.1  mrg 	  return true;
    867  1.1  mrg 	}
    868  1.1  mrg       return false;
    869  1.1  mrg 
    870  1.1  mrg     CASE_CFN_ROUNDEVEN:
    871  1.1  mrg     CASE_CFN_ROUNDEVEN_FN:
    872  1.1  mrg       if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
    873  1.1  mrg 	{
    874  1.1  mrg 	  real_roundeven (result, format, arg);
    875  1.1  mrg 	  return true;
    876  1.1  mrg 	}
    877  1.1  mrg       return false;
    878  1.1  mrg 
    879  1.1  mrg     CASE_CFN_LOGB:
    880  1.1  mrg       return fold_const_logb (result, arg, format);
    881  1.1  mrg 
    882  1.1  mrg     CASE_CFN_SIGNIFICAND:
    883  1.1  mrg       return fold_const_significand (result, arg, format);
    884  1.1  mrg 
    885  1.1  mrg     default:
    886  1.1  mrg       return false;
    887  1.1  mrg     }
    888  1.1  mrg }
    889  1.1  mrg 
    890  1.1  mrg /* Try to evaluate:
    891  1.1  mrg 
    892  1.1  mrg       *RESULT = FN (*ARG)
    893  1.1  mrg 
    894  1.1  mrg    where FORMAT is the format of ARG and PRECISION is the number of
    895  1.1  mrg    significant bits in the result.  Return true on success.  */
    896  1.1  mrg 
    897  1.1  mrg static bool
    898  1.1  mrg fold_const_call_ss (wide_int *result, combined_fn fn,
    899  1.1  mrg 		    const real_value *arg, unsigned int precision,
    900  1.1  mrg 		    const real_format *format)
    901  1.1  mrg {
    902  1.1  mrg   switch (fn)
    903  1.1  mrg     {
    904  1.1  mrg     CASE_CFN_SIGNBIT:
    905  1.1  mrg       if (real_isneg (arg))
    906  1.1  mrg 	*result = wi::one (precision);
    907  1.1  mrg       else
    908  1.1  mrg 	*result = wi::zero (precision);
    909  1.1  mrg       return true;
    910  1.1  mrg 
    911  1.1  mrg     CASE_CFN_ILOGB:
    912  1.1  mrg       /* For ilogb we don't know FP_ILOGB0, so only handle normal values.
    913  1.1  mrg 	 Proceed iff radix == 2.  In GCC, normalized significands are in
    914  1.1  mrg 	 the range [0.5, 1.0).  We want the exponent as if they were
    915  1.1  mrg 	 [1.0, 2.0) so get the exponent and subtract 1.  */
    916  1.1  mrg       if (arg->cl == rvc_normal && format->b == 2)
    917  1.1  mrg 	{
    918  1.1  mrg 	  *result = wi::shwi (REAL_EXP (arg) - 1, precision);
    919  1.1  mrg 	  return true;
    920  1.1  mrg 	}
    921  1.1  mrg       return false;
    922  1.1  mrg 
    923  1.1  mrg     CASE_CFN_ICEIL:
    924  1.1  mrg     CASE_CFN_LCEIL:
    925  1.1  mrg     CASE_CFN_LLCEIL:
    926  1.1  mrg       return fold_const_conversion (result, real_ceil, arg,
    927  1.1  mrg 				    precision, format);
    928  1.1  mrg 
    929  1.1  mrg     CASE_CFN_LFLOOR:
    930  1.1  mrg     CASE_CFN_IFLOOR:
    931  1.1  mrg     CASE_CFN_LLFLOOR:
    932  1.1  mrg       return fold_const_conversion (result, real_floor, arg,
    933  1.1  mrg 				    precision, format);
    934  1.1  mrg 
    935  1.1  mrg     CASE_CFN_IROUND:
    936  1.1  mrg     CASE_CFN_LROUND:
    937  1.1  mrg     CASE_CFN_LLROUND:
    938  1.1  mrg       return fold_const_conversion (result, real_round, arg,
    939  1.1  mrg 				    precision, format);
    940  1.1  mrg 
    941  1.1  mrg     CASE_CFN_IRINT:
    942  1.1  mrg     CASE_CFN_LRINT:
    943  1.1  mrg     CASE_CFN_LLRINT:
    944  1.1  mrg       /* Not yet folded to a constant.  */
    945  1.1  mrg       return false;
    946  1.1  mrg 
    947  1.1  mrg     CASE_CFN_FINITE:
    948  1.1  mrg     case CFN_BUILT_IN_FINITED32:
    949  1.1  mrg     case CFN_BUILT_IN_FINITED64:
    950  1.1  mrg     case CFN_BUILT_IN_FINITED128:
    951  1.1  mrg     case CFN_BUILT_IN_ISFINITE:
    952  1.1  mrg       *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
    953  1.1  mrg       return true;
    954  1.1  mrg 
    955  1.1  mrg     CASE_CFN_ISINF:
    956  1.1  mrg     case CFN_BUILT_IN_ISINFD32:
    957  1.1  mrg     case CFN_BUILT_IN_ISINFD64:
    958  1.1  mrg     case CFN_BUILT_IN_ISINFD128:
    959  1.1  mrg       if (real_isinf (arg))
    960  1.1  mrg 	*result = wi::shwi (arg->sign ? -1 : 1, precision);
    961  1.1  mrg       else
    962  1.1  mrg 	*result = wi::shwi (0, precision);
    963  1.1  mrg       return true;
    964  1.1  mrg 
    965  1.1  mrg     CASE_CFN_ISNAN:
    966  1.1  mrg     case CFN_BUILT_IN_ISNAND32:
    967  1.1  mrg     case CFN_BUILT_IN_ISNAND64:
    968  1.1  mrg     case CFN_BUILT_IN_ISNAND128:
    969  1.1  mrg       *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
    970  1.1  mrg       return true;
    971  1.1  mrg 
    972  1.1  mrg     default:
    973  1.1  mrg       return false;
    974  1.1  mrg     }
    975  1.1  mrg }
    976  1.1  mrg 
    977  1.1  mrg /* Try to evaluate:
    978  1.1  mrg 
    979  1.1  mrg       *RESULT = FN (ARG)
    980  1.1  mrg 
    981  1.1  mrg    where ARG_TYPE is the type of ARG and PRECISION is the number of bits
    982  1.1  mrg    in the result.  Return true on success.  */
    983  1.1  mrg 
    984  1.1  mrg static bool
    985  1.1  mrg fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
    986  1.1  mrg 		    unsigned int precision, tree arg_type)
    987  1.1  mrg {
    988  1.1  mrg   switch (fn)
    989  1.1  mrg     {
    990  1.1  mrg     CASE_CFN_FFS:
    991  1.1  mrg       *result = wi::shwi (wi::ffs (arg), precision);
    992  1.1  mrg       return true;
    993  1.1  mrg 
    994  1.1  mrg     CASE_CFN_CLZ:
    995  1.1  mrg       {
    996  1.1  mrg 	int tmp;
    997  1.1  mrg 	if (wi::ne_p (arg, 0))
    998  1.1  mrg 	  tmp = wi::clz (arg);
    999  1.1  mrg 	else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
   1000  1.1  mrg 					     tmp))
   1001  1.1  mrg 	  tmp = TYPE_PRECISION (arg_type);
   1002  1.1  mrg 	*result = wi::shwi (tmp, precision);
   1003  1.1  mrg 	return true;
   1004  1.1  mrg       }
   1005  1.1  mrg 
   1006  1.1  mrg     CASE_CFN_CTZ:
   1007  1.1  mrg       {
   1008  1.1  mrg 	int tmp;
   1009  1.1  mrg 	if (wi::ne_p (arg, 0))
   1010  1.1  mrg 	  tmp = wi::ctz (arg);
   1011  1.1  mrg 	else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
   1012  1.1  mrg 					     tmp))
   1013  1.1  mrg 	  tmp = TYPE_PRECISION (arg_type);
   1014  1.1  mrg 	*result = wi::shwi (tmp, precision);
   1015  1.1  mrg 	return true;
   1016  1.1  mrg       }
   1017  1.1  mrg 
   1018  1.1  mrg     CASE_CFN_CLRSB:
   1019  1.1  mrg       *result = wi::shwi (wi::clrsb (arg), precision);
   1020  1.1  mrg       return true;
   1021  1.1  mrg 
   1022  1.1  mrg     CASE_CFN_POPCOUNT:
   1023  1.1  mrg       *result = wi::shwi (wi::popcount (arg), precision);
   1024  1.1  mrg       return true;
   1025  1.1  mrg 
   1026  1.1  mrg     CASE_CFN_PARITY:
   1027  1.1  mrg       *result = wi::shwi (wi::parity (arg), precision);
   1028  1.1  mrg       return true;
   1029  1.1  mrg 
   1030  1.1  mrg     case CFN_BUILT_IN_BSWAP16:
   1031  1.1  mrg     case CFN_BUILT_IN_BSWAP32:
   1032  1.1  mrg     case CFN_BUILT_IN_BSWAP64:
   1033  1.1  mrg     case CFN_BUILT_IN_BSWAP128:
   1034  1.1  mrg       *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
   1035  1.1  mrg       return true;
   1036  1.1  mrg 
   1037  1.1  mrg     default:
   1038  1.1  mrg       return false;
   1039  1.1  mrg     }
   1040  1.1  mrg }
   1041  1.1  mrg 
   1042  1.1  mrg /* Try to evaluate:
   1043  1.1  mrg 
   1044  1.1  mrg       RESULT = FN (*ARG)
   1045  1.1  mrg 
   1046  1.1  mrg    where FORMAT is the format of ARG and of the real and imaginary parts
   1047  1.1  mrg    of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively.  Return
   1048  1.1  mrg    true on success.  */
   1049  1.1  mrg 
   1050  1.1  mrg static bool
   1051  1.1  mrg fold_const_call_cs (real_value *result_real, real_value *result_imag,
   1052  1.1  mrg 		    combined_fn fn, const real_value *arg,
   1053  1.1  mrg 		    const real_format *format)
   1054  1.1  mrg {
   1055  1.1  mrg   switch (fn)
   1056  1.1  mrg     {
   1057  1.1  mrg     CASE_CFN_CEXPI:
   1058  1.1  mrg       /* cexpi(x+yi) = cos(x)+sin(y)*i.  */
   1059  1.1  mrg       return do_mpfr_sincos (result_imag, result_real, arg, format);
   1060  1.1  mrg 
   1061  1.1  mrg     default:
   1062  1.1  mrg       return false;
   1063  1.1  mrg     }
   1064  1.1  mrg }
   1065  1.1  mrg 
   1066  1.1  mrg /* Try to evaluate:
   1067  1.1  mrg 
   1068  1.1  mrg       *RESULT = fn (ARG)
   1069  1.1  mrg 
   1070  1.1  mrg    where FORMAT is the format of RESULT and of the real and imaginary parts
   1071  1.1  mrg    of ARG, passed as ARG_REAL and ARG_IMAG respectively.  Return true on
   1072  1.1  mrg    success.  */
   1073  1.1  mrg 
   1074  1.1  mrg static bool
   1075  1.1  mrg fold_const_call_sc (real_value *result, combined_fn fn,
   1076  1.1  mrg 		    const real_value *arg_real, const real_value *arg_imag,
   1077  1.1  mrg 		    const real_format *format)
   1078  1.1  mrg {
   1079  1.1  mrg   switch (fn)
   1080  1.1  mrg     {
   1081  1.1  mrg     CASE_CFN_CABS:
   1082  1.1  mrg       return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
   1083  1.1  mrg 
   1084  1.1  mrg     default:
   1085  1.1  mrg       return false;
   1086  1.1  mrg     }
   1087  1.1  mrg }
   1088  1.1  mrg 
   1089  1.1  mrg /* Try to evaluate:
   1090  1.1  mrg 
   1091  1.1  mrg       RESULT = fn (ARG)
   1092  1.1  mrg 
   1093  1.1  mrg    where FORMAT is the format of the real and imaginary parts of RESULT
   1094  1.1  mrg    (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
   1095  1.1  mrg    Return true on success.  */
   1096  1.1  mrg 
   1097  1.1  mrg static bool
   1098  1.1  mrg fold_const_call_cc (real_value *result_real, real_value *result_imag,
   1099  1.1  mrg 		    combined_fn fn, const real_value *arg_real,
   1100  1.1  mrg 		    const real_value *arg_imag, const real_format *format)
   1101  1.1  mrg {
   1102  1.1  mrg   switch (fn)
   1103  1.1  mrg     {
   1104  1.1  mrg     CASE_CFN_CCOS:
   1105  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_cos,
   1106  1.1  mrg 			  arg_real, arg_imag, format);
   1107  1.1  mrg 
   1108  1.1  mrg     CASE_CFN_CCOSH:
   1109  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
   1110  1.1  mrg 			  arg_real, arg_imag, format);
   1111  1.1  mrg 
   1112  1.1  mrg     CASE_CFN_CPROJ:
   1113  1.1  mrg       if (real_isinf (arg_real) || real_isinf (arg_imag))
   1114  1.1  mrg 	{
   1115  1.1  mrg 	  real_inf (result_real);
   1116  1.1  mrg 	  *result_imag = dconst0;
   1117  1.1  mrg 	  result_imag->sign = arg_imag->sign;
   1118  1.1  mrg 	}
   1119  1.1  mrg       else
   1120  1.1  mrg 	{
   1121  1.1  mrg 	  *result_real = *arg_real;
   1122  1.1  mrg 	  *result_imag = *arg_imag;
   1123  1.1  mrg 	}
   1124  1.1  mrg       return true;
   1125  1.1  mrg 
   1126  1.1  mrg     CASE_CFN_CSIN:
   1127  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_sin,
   1128  1.1  mrg 			  arg_real, arg_imag, format);
   1129  1.1  mrg 
   1130  1.1  mrg     CASE_CFN_CSINH:
   1131  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
   1132  1.1  mrg 			  arg_real, arg_imag, format);
   1133  1.1  mrg 
   1134  1.1  mrg     CASE_CFN_CTAN:
   1135  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_tan,
   1136  1.1  mrg 			  arg_real, arg_imag, format);
   1137  1.1  mrg 
   1138  1.1  mrg     CASE_CFN_CTANH:
   1139  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
   1140  1.1  mrg 			  arg_real, arg_imag, format);
   1141  1.1  mrg 
   1142  1.1  mrg     CASE_CFN_CLOG:
   1143  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_log,
   1144  1.1  mrg 			  arg_real, arg_imag, format);
   1145  1.1  mrg 
   1146  1.1  mrg     CASE_CFN_CSQRT:
   1147  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
   1148  1.1  mrg 			  arg_real, arg_imag, format);
   1149  1.1  mrg 
   1150  1.1  mrg     CASE_CFN_CASIN:
   1151  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_asin,
   1152  1.1  mrg 			  arg_real, arg_imag, format);
   1153  1.1  mrg 
   1154  1.1  mrg     CASE_CFN_CACOS:
   1155  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_acos,
   1156  1.1  mrg 			  arg_real, arg_imag, format);
   1157  1.1  mrg 
   1158  1.1  mrg     CASE_CFN_CATAN:
   1159  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_atan,
   1160  1.1  mrg 			  arg_real, arg_imag, format);
   1161  1.1  mrg 
   1162  1.1  mrg     CASE_CFN_CASINH:
   1163  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
   1164  1.1  mrg 			  arg_real, arg_imag, format);
   1165  1.1  mrg 
   1166  1.1  mrg     CASE_CFN_CACOSH:
   1167  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
   1168  1.1  mrg 			  arg_real, arg_imag, format);
   1169  1.1  mrg 
   1170  1.1  mrg     CASE_CFN_CATANH:
   1171  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
   1172  1.1  mrg 			  arg_real, arg_imag, format);
   1173  1.1  mrg 
   1174  1.1  mrg     CASE_CFN_CEXP:
   1175  1.1  mrg       return do_mpc_arg1 (result_real, result_imag, mpc_exp,
   1176  1.1  mrg 			  arg_real, arg_imag, format);
   1177  1.1  mrg 
   1178  1.1  mrg     default:
   1179  1.1  mrg       return false;
   1180  1.1  mrg     }
   1181  1.1  mrg }
   1182  1.1  mrg 
   1183  1.1  mrg /* Subroutine of fold_const_call, with the same interface.  Handle cases
   1184  1.1  mrg    where the arguments and result are numerical.  */
   1185  1.1  mrg 
   1186  1.1  mrg static tree
   1187  1.1  mrg fold_const_call_1 (combined_fn fn, tree type, tree arg)
   1188  1.1  mrg {
   1189  1.1  mrg   machine_mode mode = TYPE_MODE (type);
   1190  1.1  mrg   machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
   1191  1.1  mrg 
   1192  1.1  mrg   if (integer_cst_p (arg))
   1193  1.1  mrg     {
   1194  1.1  mrg       if (SCALAR_INT_MODE_P (mode))
   1195  1.1  mrg 	{
   1196  1.1  mrg 	  wide_int result;
   1197  1.1  mrg 	  if (fold_const_call_ss (&result, fn, wi::to_wide (arg),
   1198  1.1  mrg 				  TYPE_PRECISION (type), TREE_TYPE (arg)))
   1199  1.1  mrg 	    return wide_int_to_tree (type, result);
   1200  1.1  mrg 	}
   1201  1.1  mrg       return NULL_TREE;
   1202  1.1  mrg     }
   1203  1.1  mrg 
   1204  1.1  mrg   if (real_cst_p (arg))
   1205  1.1  mrg     {
   1206  1.1  mrg       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
   1207  1.1  mrg       if (mode == arg_mode)
   1208  1.1  mrg 	{
   1209  1.1  mrg 	  /* real -> real.  */
   1210  1.1  mrg 	  REAL_VALUE_TYPE result;
   1211  1.1  mrg 	  if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
   1212  1.1  mrg 				  REAL_MODE_FORMAT (mode)))
   1213  1.1  mrg 	    return build_real (type, result);
   1214  1.1  mrg 	}
   1215  1.1  mrg       else if (COMPLEX_MODE_P (mode)
   1216  1.1  mrg 	       && GET_MODE_INNER (mode) == arg_mode)
   1217  1.1  mrg 	{
   1218  1.1  mrg 	  /* real -> complex real.  */
   1219  1.1  mrg 	  REAL_VALUE_TYPE result_real, result_imag;
   1220  1.1  mrg 	  if (fold_const_call_cs (&result_real, &result_imag, fn,
   1221  1.1  mrg 				  TREE_REAL_CST_PTR (arg),
   1222  1.1  mrg 				  REAL_MODE_FORMAT (arg_mode)))
   1223  1.1  mrg 	    return build_complex (type,
   1224  1.1  mrg 				  build_real (TREE_TYPE (type), result_real),
   1225  1.1  mrg 				  build_real (TREE_TYPE (type), result_imag));
   1226  1.1  mrg 	}
   1227  1.1  mrg       else if (INTEGRAL_TYPE_P (type))
   1228  1.1  mrg 	{
   1229  1.1  mrg 	  /* real -> int.  */
   1230  1.1  mrg 	  wide_int result;
   1231  1.1  mrg 	  if (fold_const_call_ss (&result, fn,
   1232  1.1  mrg 				  TREE_REAL_CST_PTR (arg),
   1233  1.1  mrg 				  TYPE_PRECISION (type),
   1234  1.1  mrg 				  REAL_MODE_FORMAT (arg_mode)))
   1235  1.1  mrg 	    return wide_int_to_tree (type, result);
   1236  1.1  mrg 	}
   1237  1.1  mrg       return NULL_TREE;
   1238  1.1  mrg     }
   1239  1.1  mrg 
   1240  1.1  mrg   if (complex_cst_p (arg))
   1241  1.1  mrg     {
   1242  1.1  mrg       gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
   1243  1.1  mrg       machine_mode inner_mode = GET_MODE_INNER (arg_mode);
   1244  1.1  mrg       tree argr = TREE_REALPART (arg);
   1245  1.1  mrg       tree argi = TREE_IMAGPART (arg);
   1246  1.1  mrg       if (mode == arg_mode
   1247  1.1  mrg 	  && real_cst_p (argr)
   1248  1.1  mrg 	  && real_cst_p (argi))
   1249  1.1  mrg 	{
   1250  1.1  mrg 	  /* complex real -> complex real.  */
   1251  1.1  mrg 	  REAL_VALUE_TYPE result_real, result_imag;
   1252  1.1  mrg 	  if (fold_const_call_cc (&result_real, &result_imag, fn,
   1253  1.1  mrg 				  TREE_REAL_CST_PTR (argr),
   1254  1.1  mrg 				  TREE_REAL_CST_PTR (argi),
   1255  1.1  mrg 				  REAL_MODE_FORMAT (inner_mode)))
   1256  1.1  mrg 	    return build_complex (type,
   1257  1.1  mrg 				  build_real (TREE_TYPE (type), result_real),
   1258  1.1  mrg 				  build_real (TREE_TYPE (type), result_imag));
   1259  1.1  mrg 	}
   1260  1.1  mrg       if (mode == inner_mode
   1261  1.1  mrg 	  && real_cst_p (argr)
   1262  1.1  mrg 	  && real_cst_p (argi))
   1263  1.1  mrg 	{
   1264  1.1  mrg 	  /* complex real -> real.  */
   1265  1.1  mrg 	  REAL_VALUE_TYPE result;
   1266  1.1  mrg 	  if (fold_const_call_sc (&result, fn,
   1267  1.1  mrg 				  TREE_REAL_CST_PTR (argr),
   1268  1.1  mrg 				  TREE_REAL_CST_PTR (argi),
   1269  1.1  mrg 				  REAL_MODE_FORMAT (inner_mode)))
   1270  1.1  mrg 	    return build_real (type, result);
   1271  1.1  mrg 	}
   1272  1.1  mrg       return NULL_TREE;
   1273  1.1  mrg     }
   1274  1.1  mrg 
   1275  1.1  mrg   return NULL_TREE;
   1276  1.1  mrg }
   1277  1.1  mrg 
   1278  1.1  mrg /* Try to fold FN (ARG) to a constant.  Return the constant on success,
   1279  1.1  mrg    otherwise return null.  TYPE is the type of the return value.  */
   1280  1.1  mrg 
   1281  1.1  mrg tree
   1282  1.1  mrg fold_const_call (combined_fn fn, tree type, tree arg)
   1283  1.1  mrg {
   1284  1.1  mrg   switch (fn)
   1285  1.1  mrg     {
   1286  1.1  mrg     case CFN_BUILT_IN_STRLEN:
   1287  1.1  mrg       if (const char *str = c_getstr (arg))
   1288  1.1  mrg 	return build_int_cst (type, strlen (str));
   1289  1.1  mrg       return NULL_TREE;
   1290  1.1  mrg 
   1291  1.1  mrg     CASE_CFN_NAN:
   1292  1.1  mrg     CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
   1293  1.1  mrg     case CFN_BUILT_IN_NAND32:
   1294  1.1  mrg     case CFN_BUILT_IN_NAND64:
   1295  1.1  mrg     case CFN_BUILT_IN_NAND128:
   1296  1.1  mrg       return fold_const_builtin_nan (type, arg, true);
   1297  1.1  mrg 
   1298  1.1  mrg     CASE_CFN_NANS:
   1299  1.1  mrg     CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
   1300  1.1  mrg     case CFN_BUILT_IN_NANSD32:
   1301  1.1  mrg     case CFN_BUILT_IN_NANSD64:
   1302  1.1  mrg     case CFN_BUILT_IN_NANSD128:
   1303  1.1  mrg       return fold_const_builtin_nan (type, arg, false);
   1304  1.1  mrg 
   1305  1.1  mrg     case CFN_REDUC_PLUS:
   1306  1.1  mrg       return fold_const_reduction (type, arg, PLUS_EXPR);
   1307  1.1  mrg 
   1308  1.1  mrg     case CFN_REDUC_MAX:
   1309  1.1  mrg       return fold_const_reduction (type, arg, MAX_EXPR);
   1310  1.1  mrg 
   1311  1.1  mrg     case CFN_REDUC_MIN:
   1312  1.1  mrg       return fold_const_reduction (type, arg, MIN_EXPR);
   1313  1.1  mrg 
   1314  1.1  mrg     case CFN_REDUC_AND:
   1315  1.1  mrg       return fold_const_reduction (type, arg, BIT_AND_EXPR);
   1316  1.1  mrg 
   1317  1.1  mrg     case CFN_REDUC_IOR:
   1318  1.1  mrg       return fold_const_reduction (type, arg, BIT_IOR_EXPR);
   1319  1.1  mrg 
   1320  1.1  mrg     case CFN_REDUC_XOR:
   1321  1.1  mrg       return fold_const_reduction (type, arg, BIT_XOR_EXPR);
   1322  1.1  mrg 
   1323  1.1  mrg     case CFN_VEC_CONVERT:
   1324  1.1  mrg       return fold_const_vec_convert (type, arg);
   1325  1.1  mrg 
   1326  1.1  mrg     default:
   1327  1.1  mrg       return fold_const_call_1 (fn, type, arg);
   1328  1.1  mrg     }
   1329  1.1  mrg }
   1330  1.1  mrg 
   1331  1.1  mrg /* Fold a call to IFN_FOLD_LEFT_<CODE> (ARG0, ARG1), returning a value
   1332  1.1  mrg    of type TYPE.  */
   1333  1.1  mrg 
   1334  1.1  mrg static tree
   1335  1.1  mrg fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code)
   1336  1.1  mrg {
   1337  1.1  mrg   if (TREE_CODE (arg1) != VECTOR_CST)
   1338  1.1  mrg     return NULL_TREE;
   1339  1.1  mrg 
   1340  1.1  mrg   unsigned HOST_WIDE_INT nelts;
   1341  1.1  mrg   if (!VECTOR_CST_NELTS (arg1).is_constant (&nelts))
   1342  1.1  mrg     return NULL_TREE;
   1343  1.1  mrg 
   1344  1.1  mrg   for (unsigned HOST_WIDE_INT i = 0; i < nelts; i++)
   1345  1.1  mrg     {
   1346  1.1  mrg       arg0 = const_binop (code, type, arg0, VECTOR_CST_ELT (arg1, i));
   1347  1.1  mrg       if (arg0 == NULL_TREE || !CONSTANT_CLASS_P (arg0))
   1348  1.1  mrg 	return NULL_TREE;
   1349  1.1  mrg     }
   1350  1.1  mrg   return arg0;
   1351  1.1  mrg }
   1352  1.1  mrg 
   1353  1.1  mrg /* Try to evaluate:
   1354  1.1  mrg 
   1355  1.1  mrg       *RESULT = FN (*ARG0, *ARG1)
   1356  1.1  mrg 
   1357  1.1  mrg    in format FORMAT.  Return true on success.  */
   1358  1.1  mrg 
   1359  1.1  mrg static bool
   1360  1.1  mrg fold_const_call_sss (real_value *result, combined_fn fn,
   1361  1.1  mrg 		     const real_value *arg0, const real_value *arg1,
   1362  1.1  mrg 		     const real_format *format)
   1363  1.1  mrg {
   1364  1.1  mrg   switch (fn)
   1365  1.1  mrg     {
   1366  1.1  mrg     CASE_CFN_DREM:
   1367  1.1  mrg     CASE_CFN_REMAINDER:
   1368  1.1  mrg       return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
   1369  1.1  mrg 
   1370  1.1  mrg     CASE_CFN_ATAN2:
   1371  1.1  mrg       return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
   1372  1.1  mrg 
   1373  1.1  mrg     CASE_CFN_FDIM:
   1374  1.1  mrg       return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
   1375  1.1  mrg 
   1376  1.1  mrg     CASE_CFN_FMOD:
   1377  1.1  mrg       return do_mpfr_arg2 (result, mpfr_fmod, arg0, arg1, format);
   1378  1.1  mrg 
   1379  1.1  mrg     CASE_CFN_HYPOT:
   1380  1.1  mrg       return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
   1381  1.1  mrg 
   1382  1.1  mrg     CASE_CFN_COPYSIGN:
   1383  1.1  mrg     CASE_CFN_COPYSIGN_FN:
   1384  1.1  mrg       *result = *arg0;
   1385  1.1  mrg       real_copysign (result, arg1);
   1386  1.1  mrg       return true;
   1387  1.1  mrg 
   1388  1.1  mrg     CASE_CFN_FMIN:
   1389  1.1  mrg     CASE_CFN_FMIN_FN:
   1390  1.1  mrg       return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
   1391  1.1  mrg 
   1392  1.1  mrg     CASE_CFN_FMAX:
   1393  1.1  mrg     CASE_CFN_FMAX_FN:
   1394  1.1  mrg       return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
   1395  1.1  mrg 
   1396  1.1  mrg     CASE_CFN_POW:
   1397  1.1  mrg       return fold_const_pow (result, arg0, arg1, format);
   1398  1.1  mrg 
   1399  1.1  mrg     CASE_CFN_NEXTAFTER:
   1400  1.1  mrg     CASE_CFN_NEXTTOWARD:
   1401  1.1  mrg       return fold_const_nextafter (result, arg0, arg1, format);
   1402  1.1  mrg 
   1403  1.1  mrg     default:
   1404  1.1  mrg       return false;
   1405  1.1  mrg     }
   1406  1.1  mrg }
   1407  1.1  mrg 
   1408  1.1  mrg /* Try to evaluate:
   1409  1.1  mrg 
   1410  1.1  mrg       *RESULT = FN (*ARG0, ARG1)
   1411  1.1  mrg 
   1412  1.1  mrg    where FORMAT is the format of *RESULT and *ARG0.  Return true on
   1413  1.1  mrg    success.  */
   1414  1.1  mrg 
   1415  1.1  mrg static bool
   1416  1.1  mrg fold_const_call_sss (real_value *result, combined_fn fn,
   1417  1.1  mrg 		     const real_value *arg0, const wide_int_ref &arg1,
   1418  1.1  mrg 		     const real_format *format)
   1419  1.1  mrg {
   1420  1.1  mrg   switch (fn)
   1421  1.1  mrg     {
   1422  1.1  mrg     CASE_CFN_LDEXP:
   1423  1.1  mrg       return fold_const_builtin_load_exponent (result, arg0, arg1, format);
   1424  1.1  mrg 
   1425  1.1  mrg     CASE_CFN_SCALBN:
   1426  1.1  mrg     CASE_CFN_SCALBLN:
   1427  1.1  mrg       return (format->b == 2
   1428  1.1  mrg 	      && fold_const_builtin_load_exponent (result, arg0, arg1,
   1429  1.1  mrg 						   format));
   1430  1.1  mrg 
   1431  1.1  mrg     CASE_CFN_POWI:
   1432  1.1  mrg       /* Avoid the folding if flag_signaling_nans is on and
   1433  1.1  mrg          operand is a signaling NaN.  */
   1434  1.1  mrg       if (!flag_unsafe_math_optimizations
   1435  1.1  mrg 	  && flag_signaling_nans
   1436  1.1  mrg 	  && REAL_VALUE_ISSIGNALING_NAN (*arg0))
   1437  1.1  mrg         return false;
   1438  1.1  mrg 
   1439  1.1  mrg       real_powi (result, format, arg0, arg1.to_shwi ());
   1440  1.1  mrg       return true;
   1441  1.1  mrg 
   1442  1.1  mrg     default:
   1443  1.1  mrg       return false;
   1444  1.1  mrg     }
   1445  1.1  mrg }
   1446  1.1  mrg 
   1447  1.1  mrg /* Try to evaluate:
   1448  1.1  mrg 
   1449  1.1  mrg       *RESULT = FN (ARG0, *ARG1)
   1450  1.1  mrg 
   1451  1.1  mrg    where FORMAT is the format of *RESULT and *ARG1.  Return true on
   1452  1.1  mrg    success.  */
   1453  1.1  mrg 
   1454  1.1  mrg static bool
   1455  1.1  mrg fold_const_call_sss (real_value *result, combined_fn fn,
   1456  1.1  mrg 		     const wide_int_ref &arg0, const real_value *arg1,
   1457  1.1  mrg 		     const real_format *format)
   1458  1.1  mrg {
   1459  1.1  mrg   switch (fn)
   1460  1.1  mrg     {
   1461  1.1  mrg     CASE_CFN_JN:
   1462  1.1  mrg       return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
   1463  1.1  mrg 
   1464  1.1  mrg     CASE_CFN_YN:
   1465  1.1  mrg       return (real_compare (GT_EXPR, arg1, &dconst0)
   1466  1.1  mrg 	      && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
   1467  1.1  mrg 
   1468  1.1  mrg     default:
   1469  1.1  mrg       return false;
   1470  1.1  mrg     }
   1471  1.1  mrg }
   1472  1.1  mrg 
   1473  1.1  mrg /* Try to evaluate:
   1474  1.1  mrg 
   1475  1.1  mrg       RESULT = fn (ARG0, ARG1)
   1476  1.1  mrg 
   1477  1.1  mrg    where FORMAT is the format of the real and imaginary parts of RESULT
   1478  1.1  mrg    (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
   1479  1.1  mrg    and of ARG1 (ARG1_REAL and ARG1_IMAG).  Return true on success.  */
   1480  1.1  mrg 
   1481  1.1  mrg static bool
   1482  1.1  mrg fold_const_call_ccc (real_value *result_real, real_value *result_imag,
   1483  1.1  mrg 		     combined_fn fn, const real_value *arg0_real,
   1484  1.1  mrg 		     const real_value *arg0_imag, const real_value *arg1_real,
   1485  1.1  mrg 		     const real_value *arg1_imag, const real_format *format)
   1486  1.1  mrg {
   1487  1.1  mrg   switch (fn)
   1488  1.1  mrg     {
   1489  1.1  mrg     CASE_CFN_CPOW:
   1490  1.1  mrg       return do_mpc_arg2 (result_real, result_imag, mpc_pow,
   1491  1.1  mrg 			  arg0_real, arg0_imag, arg1_real, arg1_imag, format);
   1492  1.1  mrg 
   1493  1.1  mrg     default:
   1494  1.1  mrg       return false;
   1495  1.1  mrg     }
   1496  1.1  mrg }
   1497  1.1  mrg 
   1498  1.1  mrg /* Subroutine of fold_const_call, with the same interface.  Handle cases
   1499  1.1  mrg    where the arguments and result are numerical.  */
   1500  1.1  mrg 
   1501  1.1  mrg static tree
   1502  1.1  mrg fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
   1503  1.1  mrg {
   1504  1.1  mrg   machine_mode mode = TYPE_MODE (type);
   1505  1.1  mrg   machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
   1506  1.1  mrg   machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
   1507  1.1  mrg 
   1508  1.1  mrg   if (mode == arg0_mode
   1509  1.1  mrg       && real_cst_p (arg0)
   1510  1.1  mrg       && real_cst_p (arg1))
   1511  1.1  mrg     {
   1512  1.1  mrg       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
   1513  1.1  mrg       REAL_VALUE_TYPE result;
   1514  1.1  mrg       if (arg0_mode == arg1_mode)
   1515  1.1  mrg 	{
   1516  1.1  mrg 	  /* real, real -> real.  */
   1517  1.1  mrg 	  if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
   1518  1.1  mrg 				   TREE_REAL_CST_PTR (arg1),
   1519  1.1  mrg 				   REAL_MODE_FORMAT (mode)))
   1520  1.1  mrg 	    return build_real (type, result);
   1521  1.1  mrg 	}
   1522  1.1  mrg       else if (arg1_mode == TYPE_MODE (long_double_type_node))
   1523  1.1  mrg 	switch (fn)
   1524  1.1  mrg 	  {
   1525  1.1  mrg 	  CASE_CFN_NEXTTOWARD:
   1526  1.1  mrg 	    /* real, long double -> real.  */
   1527  1.1  mrg 	    if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
   1528  1.1  mrg 				     TREE_REAL_CST_PTR (arg1),
   1529  1.1  mrg 				     REAL_MODE_FORMAT (mode)))
   1530  1.1  mrg 	      return build_real (type, result);
   1531  1.1  mrg 	    break;
   1532  1.1  mrg 	  default:
   1533  1.1  mrg 	    break;
   1534  1.1  mrg 	  }
   1535  1.1  mrg       return NULL_TREE;
   1536  1.1  mrg     }
   1537  1.1  mrg 
   1538  1.1  mrg   if (real_cst_p (arg0)
   1539  1.1  mrg       && integer_cst_p (arg1))
   1540  1.1  mrg     {
   1541  1.1  mrg       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
   1542  1.1  mrg       if (mode == arg0_mode)
   1543  1.1  mrg 	{
   1544  1.1  mrg 	  /* real, int -> real.  */
   1545  1.1  mrg 	  REAL_VALUE_TYPE result;
   1546  1.1  mrg 	  if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
   1547  1.1  mrg 				   wi::to_wide (arg1),
   1548  1.1  mrg 				   REAL_MODE_FORMAT (mode)))
   1549  1.1  mrg 	    return build_real (type, result);
   1550  1.1  mrg 	}
   1551  1.1  mrg       return NULL_TREE;
   1552  1.1  mrg     }
   1553  1.1  mrg 
   1554  1.1  mrg   if (integer_cst_p (arg0)
   1555  1.1  mrg       && real_cst_p (arg1))
   1556  1.1  mrg     {
   1557  1.1  mrg       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
   1558  1.1  mrg       if (mode == arg1_mode)
   1559  1.1  mrg 	{
   1560  1.1  mrg 	  /* int, real -> real.  */
   1561  1.1  mrg 	  REAL_VALUE_TYPE result;
   1562  1.1  mrg 	  if (fold_const_call_sss (&result, fn, wi::to_wide (arg0),
   1563  1.1  mrg 				   TREE_REAL_CST_PTR (arg1),
   1564  1.1  mrg 				   REAL_MODE_FORMAT (mode)))
   1565  1.1  mrg 	    return build_real (type, result);
   1566  1.1  mrg 	}
   1567  1.1  mrg       return NULL_TREE;
   1568  1.1  mrg     }
   1569  1.1  mrg 
   1570  1.1  mrg   if (arg0_mode == arg1_mode
   1571  1.1  mrg       && complex_cst_p (arg0)
   1572  1.1  mrg       && complex_cst_p (arg1))
   1573  1.1  mrg     {
   1574  1.1  mrg       gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
   1575  1.1  mrg       machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
   1576  1.1  mrg       tree arg0r = TREE_REALPART (arg0);
   1577  1.1  mrg       tree arg0i = TREE_IMAGPART (arg0);
   1578  1.1  mrg       tree arg1r = TREE_REALPART (arg1);
   1579  1.1  mrg       tree arg1i = TREE_IMAGPART (arg1);
   1580  1.1  mrg       if (mode == arg0_mode
   1581  1.1  mrg 	  && real_cst_p (arg0r)
   1582  1.1  mrg 	  && real_cst_p (arg0i)
   1583  1.1  mrg 	  && real_cst_p (arg1r)
   1584  1.1  mrg 	  && real_cst_p (arg1i))
   1585  1.1  mrg 	{
   1586  1.1  mrg 	  /* complex real, complex real -> complex real.  */
   1587  1.1  mrg 	  REAL_VALUE_TYPE result_real, result_imag;
   1588  1.1  mrg 	  if (fold_const_call_ccc (&result_real, &result_imag, fn,
   1589  1.1  mrg 				   TREE_REAL_CST_PTR (arg0r),
   1590  1.1  mrg 				   TREE_REAL_CST_PTR (arg0i),
   1591  1.1  mrg 				   TREE_REAL_CST_PTR (arg1r),
   1592  1.1  mrg 				   TREE_REAL_CST_PTR (arg1i),
   1593  1.1  mrg 				   REAL_MODE_FORMAT (inner_mode)))
   1594  1.1  mrg 	    return build_complex (type,
   1595  1.1  mrg 				  build_real (TREE_TYPE (type), result_real),
   1596  1.1  mrg 				  build_real (TREE_TYPE (type), result_imag));
   1597  1.1  mrg 	}
   1598  1.1  mrg       return NULL_TREE;
   1599  1.1  mrg     }
   1600  1.1  mrg 
   1601  1.1  mrg   return NULL_TREE;
   1602  1.1  mrg }
   1603  1.1  mrg 
   1604  1.1  mrg /* Try to fold FN (ARG0, ARG1) to a constant.  Return the constant on success,
   1605  1.1  mrg    otherwise return null.  TYPE is the type of the return value.  */
   1606  1.1  mrg 
   1607  1.1  mrg tree
   1608  1.1  mrg fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
   1609  1.1  mrg {
   1610  1.1  mrg   const char *p0, *p1;
   1611  1.1  mrg   char c;
   1612  1.1  mrg   switch (fn)
   1613  1.1  mrg     {
   1614  1.1  mrg     case CFN_BUILT_IN_STRSPN:
   1615  1.1  mrg       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
   1616  1.1  mrg 	return build_int_cst (type, strspn (p0, p1));
   1617  1.1  mrg       return NULL_TREE;
   1618  1.1  mrg 
   1619  1.1  mrg     case CFN_BUILT_IN_STRCSPN:
   1620  1.1  mrg       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
   1621  1.1  mrg 	return build_int_cst (type, strcspn (p0, p1));
   1622  1.1  mrg       return NULL_TREE;
   1623  1.1  mrg 
   1624  1.1  mrg     case CFN_BUILT_IN_STRCMP:
   1625  1.1  mrg       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
   1626  1.1  mrg 	return build_cmp_result (type, strcmp (p0, p1));
   1627  1.1  mrg       return NULL_TREE;
   1628  1.1  mrg 
   1629  1.1  mrg     case CFN_BUILT_IN_STRCASECMP:
   1630  1.1  mrg       if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
   1631  1.1  mrg 	{
   1632  1.1  mrg 	  int r = strcmp (p0, p1);
   1633  1.1  mrg 	  if (r == 0)
   1634  1.1  mrg 	    return build_cmp_result (type, r);
   1635  1.1  mrg 	}
   1636  1.1  mrg       return NULL_TREE;
   1637  1.1  mrg 
   1638  1.1  mrg     case CFN_BUILT_IN_INDEX:
   1639  1.1  mrg     case CFN_BUILT_IN_STRCHR:
   1640  1.1  mrg       if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
   1641  1.1  mrg 	{
   1642  1.1  mrg 	  const char *r = strchr (p0, c);
   1643  1.1  mrg 	  if (r == NULL)
   1644  1.1  mrg 	    return build_int_cst (type, 0);
   1645  1.1  mrg 	  return fold_convert (type,
   1646  1.1  mrg 			       fold_build_pointer_plus_hwi (arg0, r - p0));
   1647  1.1  mrg 	}
   1648  1.1  mrg       return NULL_TREE;
   1649  1.1  mrg 
   1650  1.1  mrg     case CFN_BUILT_IN_RINDEX:
   1651  1.1  mrg     case CFN_BUILT_IN_STRRCHR:
   1652  1.1  mrg       if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
   1653  1.1  mrg 	{
   1654  1.1  mrg 	  const char *r = strrchr (p0, c);
   1655  1.1  mrg 	  if (r == NULL)
   1656  1.1  mrg 	    return build_int_cst (type, 0);
   1657  1.1  mrg 	  return fold_convert (type,
   1658  1.1  mrg 			       fold_build_pointer_plus_hwi (arg0, r - p0));
   1659  1.1  mrg 	}
   1660  1.1  mrg       return NULL_TREE;
   1661  1.1  mrg 
   1662  1.1  mrg     case CFN_BUILT_IN_STRSTR:
   1663  1.1  mrg       if ((p1 = c_getstr (arg1)))
   1664  1.1  mrg 	{
   1665  1.1  mrg 	  if ((p0 = c_getstr (arg0)))
   1666  1.1  mrg 	    {
   1667  1.1  mrg 	      const char *r = strstr (p0, p1);
   1668  1.1  mrg 	      if (r == NULL)
   1669  1.1  mrg 		return build_int_cst (type, 0);
   1670  1.1  mrg 	      return fold_convert (type,
   1671  1.1  mrg 				   fold_build_pointer_plus_hwi (arg0, r - p0));
   1672  1.1  mrg 	    }
   1673  1.1  mrg 	  if (*p1 == '\0')
   1674  1.1  mrg 	    return fold_convert (type, arg0);
   1675  1.1  mrg 	}
   1676  1.1  mrg       return NULL_TREE;
   1677  1.1  mrg 
   1678  1.1  mrg     case CFN_FOLD_LEFT_PLUS:
   1679  1.1  mrg       return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR);
   1680  1.1  mrg 
   1681  1.1  mrg     default:
   1682  1.1  mrg       return fold_const_call_1 (fn, type, arg0, arg1);
   1683  1.1  mrg     }
   1684  1.1  mrg }
   1685  1.1  mrg 
   1686  1.1  mrg /* Try to evaluate:
   1687  1.1  mrg 
   1688  1.1  mrg       *RESULT = FN (*ARG0, *ARG1, *ARG2)
   1689  1.1  mrg 
   1690  1.1  mrg    in format FORMAT.  Return true on success.  */
   1691  1.1  mrg 
   1692  1.1  mrg static bool
   1693  1.1  mrg fold_const_call_ssss (real_value *result, combined_fn fn,
   1694  1.1  mrg 		      const real_value *arg0, const real_value *arg1,
   1695  1.1  mrg 		      const real_value *arg2, const real_format *format)
   1696  1.1  mrg {
   1697  1.1  mrg   switch (fn)
   1698  1.1  mrg     {
   1699  1.1  mrg     CASE_CFN_FMA:
   1700  1.1  mrg     CASE_CFN_FMA_FN:
   1701  1.1  mrg       return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
   1702  1.1  mrg 
   1703  1.1  mrg     case CFN_FMS:
   1704  1.1  mrg       {
   1705  1.1  mrg 	real_value new_arg2 = real_value_negate (arg2);
   1706  1.1  mrg 	return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, &new_arg2, format);
   1707  1.1  mrg       }
   1708  1.1  mrg 
   1709  1.1  mrg     case CFN_FNMA:
   1710  1.1  mrg       {
   1711  1.1  mrg 	real_value new_arg0 = real_value_negate (arg0);
   1712  1.1  mrg 	return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1, arg2, format);
   1713  1.1  mrg       }
   1714  1.1  mrg 
   1715  1.1  mrg     case CFN_FNMS:
   1716  1.1  mrg       {
   1717  1.1  mrg 	real_value new_arg0 = real_value_negate (arg0);
   1718  1.1  mrg 	real_value new_arg2 = real_value_negate (arg2);
   1719  1.1  mrg 	return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1,
   1720  1.1  mrg 			     &new_arg2, format);
   1721  1.1  mrg       }
   1722  1.1  mrg 
   1723  1.1  mrg     default:
   1724  1.1  mrg       return false;
   1725  1.1  mrg     }
   1726  1.1  mrg }
   1727  1.1  mrg 
   1728  1.1  mrg /* Subroutine of fold_const_call, with the same interface.  Handle cases
   1729  1.1  mrg    where the arguments and result are numerical.  */
   1730  1.1  mrg 
   1731  1.1  mrg static tree
   1732  1.1  mrg fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
   1733  1.1  mrg {
   1734  1.1  mrg   machine_mode mode = TYPE_MODE (type);
   1735  1.1  mrg   machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
   1736  1.1  mrg   machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
   1737  1.1  mrg   machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
   1738  1.1  mrg 
   1739  1.1  mrg   if (arg0_mode == arg1_mode
   1740  1.1  mrg       && arg0_mode == arg2_mode
   1741  1.1  mrg       && real_cst_p (arg0)
   1742  1.1  mrg       && real_cst_p (arg1)
   1743  1.1  mrg       && real_cst_p (arg2))
   1744  1.1  mrg     {
   1745  1.1  mrg       gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
   1746  1.1  mrg       if (mode == arg0_mode)
   1747  1.1  mrg 	{
   1748  1.1  mrg 	  /* real, real, real -> real.  */
   1749  1.1  mrg 	  REAL_VALUE_TYPE result;
   1750  1.1  mrg 	  if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
   1751  1.1  mrg 				    TREE_REAL_CST_PTR (arg1),
   1752  1.1  mrg 				    TREE_REAL_CST_PTR (arg2),
   1753  1.1  mrg 				    REAL_MODE_FORMAT (mode)))
   1754  1.1  mrg 	    return build_real (type, result);
   1755  1.1  mrg 	}
   1756  1.1  mrg       return NULL_TREE;
   1757  1.1  mrg     }
   1758  1.1  mrg 
   1759  1.1  mrg   return NULL_TREE;
   1760  1.1  mrg }
   1761  1.1  mrg 
   1762  1.1  mrg /* Try to fold FN (ARG0, ARG1, ARG2) to a constant.  Return the constant on
   1763  1.1  mrg    success, otherwise return null.  TYPE is the type of the return value.  */
   1764  1.1  mrg 
   1765  1.1  mrg tree
   1766  1.1  mrg fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
   1767  1.1  mrg {
   1768  1.1  mrg   const char *p0, *p1;
   1769  1.1  mrg   char c;
   1770  1.1  mrg   unsigned HOST_WIDE_INT s0, s1, s2 = 0;
   1771  1.1  mrg   switch (fn)
   1772  1.1  mrg     {
   1773  1.1  mrg     case CFN_BUILT_IN_STRNCMP:
   1774  1.1  mrg       if (!size_t_cst_p (arg2, &s2))
   1775  1.1  mrg 	return NULL_TREE;
   1776  1.1  mrg       if (s2 == 0
   1777  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg0)
   1778  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg1))
   1779  1.1  mrg 	return build_int_cst (type, 0);
   1780  1.1  mrg       else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
   1781  1.1  mrg 	return build_int_cst (type, strncmp (p0, p1, MIN (s2, SIZE_MAX)));
   1782  1.1  mrg       return NULL_TREE;
   1783  1.1  mrg 
   1784  1.1  mrg     case CFN_BUILT_IN_STRNCASECMP:
   1785  1.1  mrg       if (!size_t_cst_p (arg2, &s2))
   1786  1.1  mrg 	return NULL_TREE;
   1787  1.1  mrg       if (s2 == 0
   1788  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg0)
   1789  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg1))
   1790  1.1  mrg 	return build_int_cst (type, 0);
   1791  1.1  mrg       else if ((p0 = c_getstr (arg0))
   1792  1.1  mrg 	       && (p1 = c_getstr (arg1))
   1793  1.1  mrg 	       && strncmp (p0, p1, MIN (s2, SIZE_MAX)) == 0)
   1794  1.1  mrg 	return build_int_cst (type, 0);
   1795  1.1  mrg       return NULL_TREE;
   1796  1.1  mrg 
   1797  1.1  mrg     case CFN_BUILT_IN_BCMP:
   1798  1.1  mrg     case CFN_BUILT_IN_MEMCMP:
   1799  1.1  mrg       if (!size_t_cst_p (arg2, &s2))
   1800  1.1  mrg 	return NULL_TREE;
   1801  1.1  mrg       if (s2 == 0
   1802  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg0)
   1803  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg1))
   1804  1.1  mrg 	return build_int_cst (type, 0);
   1805  1.1  mrg       if ((p0 = getbyterep (arg0, &s0))
   1806  1.1  mrg 	  && (p1 = getbyterep (arg1, &s1))
   1807  1.1  mrg 	  && s2 <= s0
   1808  1.1  mrg 	  && s2 <= s1)
   1809  1.1  mrg 	return build_cmp_result (type, memcmp (p0, p1, s2));
   1810  1.1  mrg       return NULL_TREE;
   1811  1.1  mrg 
   1812  1.1  mrg     case CFN_BUILT_IN_MEMCHR:
   1813  1.1  mrg       if (!size_t_cst_p (arg2, &s2))
   1814  1.1  mrg 	return NULL_TREE;
   1815  1.1  mrg       if (s2 == 0
   1816  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg0)
   1817  1.1  mrg 	  && !TREE_SIDE_EFFECTS (arg1))
   1818  1.1  mrg 	return build_int_cst (type, 0);
   1819  1.1  mrg       if ((p0 = getbyterep (arg0, &s0))
   1820  1.1  mrg 	  && s2 <= s0
   1821  1.1  mrg 	  && target_char_cst_p (arg1, &c))
   1822  1.1  mrg 	{
   1823  1.1  mrg 	  const char *r = (const char *) memchr (p0, c, s2);
   1824  1.1  mrg 	  if (r == NULL)
   1825  1.1  mrg 	    return build_int_cst (type, 0);
   1826  1.1  mrg 	  return fold_convert (type,
   1827  1.1  mrg 			       fold_build_pointer_plus_hwi (arg0, r - p0));
   1828  1.1  mrg 	}
   1829  1.1  mrg       return NULL_TREE;
   1830  1.1  mrg 
   1831  1.1  mrg     case CFN_WHILE_ULT:
   1832  1.1  mrg       {
   1833  1.1  mrg 	poly_uint64 parg0, parg1;
   1834  1.1  mrg 	if (poly_int_tree_p (arg0, &parg0) && poly_int_tree_p (arg1, &parg1))
   1835  1.1  mrg 	  return fold_while_ult (type, parg0, parg1);
   1836  1.1  mrg 	return NULL_TREE;
   1837  1.1  mrg       }
   1838  1.1  mrg 
   1839  1.1  mrg     default:
   1840  1.1  mrg       return fold_const_call_1 (fn, type, arg0, arg1, arg2);
   1841  1.1  mrg     }
   1842  1.1  mrg }
   1843