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