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