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