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