LCOV - code coverage report
Current view: top level - gcc - fold-const-call.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.6 % 1033 977
Test Date: 2024-03-23 14:05:01 Functions: 85.7 % 42 36
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.0-1

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.