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