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 }
1680