Daily bump.
[gcc.git] / gcc / fold-const-call.c
1 /* Constant folding for calls to built-in and internal functions.
2 Copyright (C) 1988-2021 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, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
134 mpfr_t m;
135
136 mpfr_init2 (m, prec);
137 mpfr_from_real (m, arg, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
164 mpfr_t m, ms, mc;
165
166 mpfr_inits2 (prec, m, ms, mc, NULL);
167 mpfr_from_real (m, arg, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
197 mpfr_t m0, m1;
198
199 mpfr_inits2 (prec, m0, m1, NULL);
200 mpfr_from_real (m0, arg0, MPFR_RNDN);
201 mpfr_from_real (m1, arg1, MPFR_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, mpfr_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
228 mpfr_t m;
229
230 mpfr_init2 (m, prec);
231 mpfr_from_real (m, arg1, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN;
264 mpfr_t m0, m1, m2;
265
266 mpfr_inits2 (prec, m0, m1, m2, NULL);
267 mpfr_from_real (m0, arg0, MPFR_RNDN);
268 mpfr_from_real (m1, arg1, MPFR_RNDN);
269 mpfr_from_real (m2, arg2, MPFR_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, MPFR_RNDN);
300 real_from_mpfr (&tmp_imag, mpc_imagref (m), format, MPFR_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, MPFR_RNDN);
345 mpfr_from_real (mpc_imagref (m), arg_imag, MPFR_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, MPFR_RNDN);
382 mpfr_from_real (mpc_imagref (m0), arg0_imag, MPFR_RNDN);
383 mpfr_from_real (mpc_realref (m1), arg1_real, MPFR_RNDN);
384 mpfr_from_real (mpc_imagref (m1), arg1_imag, MPFR_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 /* We can't handle steps directly when extending, since the
669 values need to wrap at the original precision first. */
670 bool step_ok_p
671 = (INTEGRAL_TYPE_P (TREE_TYPE (ret_type))
672 && INTEGRAL_TYPE_P (TREE_TYPE (arg_type))
673 && (TYPE_PRECISION (TREE_TYPE (ret_type))
674 <= TYPE_PRECISION (TREE_TYPE (arg_type))));
675 tree_vector_builder elts;
676 if (!elts.new_unary_operation (ret_type, arg, step_ok_p))
677 return NULL_TREE;
678
679 unsigned int count = elts.encoded_nelts ();
680 for (unsigned int i = 0; i < count; ++i)
681 {
682 tree elt = fold_unary (code, TREE_TYPE (ret_type),
683 VECTOR_CST_ELT (arg, i));
684 if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt))
685 return NULL_TREE;
686 elts.quick_push (elt);
687 }
688
689 return elts.build ();
690 }
691
692 /* Try to evaluate:
693
694 IFN_WHILE_ULT (ARG0, ARG1, (TYPE) { ... })
695
696 Return the value on success and null on failure. */
697
698 static tree
699 fold_while_ult (tree type, poly_uint64 arg0, poly_uint64 arg1)
700 {
701 if (known_ge (arg0, arg1))
702 return build_zero_cst (type);
703
704 if (maybe_ge (arg0, arg1))
705 return NULL_TREE;
706
707 poly_uint64 diff = arg1 - arg0;
708 poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
709 if (known_ge (diff, nelts))
710 return build_all_ones_cst (type);
711
712 unsigned HOST_WIDE_INT const_diff;
713 if (known_le (diff, nelts) && diff.is_constant (&const_diff))
714 {
715 tree minus_one = build_minus_one_cst (TREE_TYPE (type));
716 tree zero = build_zero_cst (TREE_TYPE (type));
717 return build_vector_a_then_b (type, const_diff, minus_one, zero);
718 }
719 return NULL_TREE;
720 }
721
722 /* Try to evaluate:
723
724 *RESULT = FN (*ARG)
725
726 in format FORMAT. Return true on success. */
727
728 static bool
729 fold_const_call_ss (real_value *result, combined_fn fn,
730 const real_value *arg, const real_format *format)
731 {
732 switch (fn)
733 {
734 CASE_CFN_SQRT:
735 CASE_CFN_SQRT_FN:
736 return (real_compare (GE_EXPR, arg, &dconst0)
737 && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
738
739 CASE_CFN_CBRT:
740 return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
741
742 CASE_CFN_ASIN:
743 return (real_compare (GE_EXPR, arg, &dconstm1)
744 && real_compare (LE_EXPR, arg, &dconst1)
745 && do_mpfr_arg1 (result, mpfr_asin, arg, format));
746
747 CASE_CFN_ACOS:
748 return (real_compare (GE_EXPR, arg, &dconstm1)
749 && real_compare (LE_EXPR, arg, &dconst1)
750 && do_mpfr_arg1 (result, mpfr_acos, arg, format));
751
752 CASE_CFN_ATAN:
753 return do_mpfr_arg1 (result, mpfr_atan, arg, format);
754
755 CASE_CFN_ASINH:
756 return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
757
758 CASE_CFN_ACOSH:
759 return (real_compare (GE_EXPR, arg, &dconst1)
760 && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
761
762 CASE_CFN_ATANH:
763 return (real_compare (GE_EXPR, arg, &dconstm1)
764 && real_compare (LE_EXPR, arg, &dconst1)
765 && do_mpfr_arg1 (result, mpfr_atanh, arg, format));
766
767 CASE_CFN_SIN:
768 return do_mpfr_arg1 (result, mpfr_sin, arg, format);
769
770 CASE_CFN_COS:
771 return do_mpfr_arg1 (result, mpfr_cos, arg, format);
772
773 CASE_CFN_TAN:
774 return do_mpfr_arg1 (result, mpfr_tan, arg, format);
775
776 CASE_CFN_SINH:
777 return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
778
779 CASE_CFN_COSH:
780 return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
781
782 CASE_CFN_TANH:
783 return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
784
785 CASE_CFN_ERF:
786 return do_mpfr_arg1 (result, mpfr_erf, arg, format);
787
788 CASE_CFN_ERFC:
789 return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
790
791 CASE_CFN_TGAMMA:
792 return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
793
794 CASE_CFN_EXP:
795 return do_mpfr_arg1 (result, mpfr_exp, arg, format);
796
797 CASE_CFN_EXP2:
798 return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
799
800 CASE_CFN_EXP10:
801 CASE_CFN_POW10:
802 return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
803
804 CASE_CFN_EXPM1:
805 return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
806
807 CASE_CFN_LOG:
808 return (real_compare (GT_EXPR, arg, &dconst0)
809 && do_mpfr_arg1 (result, mpfr_log, arg, format));
810
811 CASE_CFN_LOG2:
812 return (real_compare (GT_EXPR, arg, &dconst0)
813 && do_mpfr_arg1 (result, mpfr_log2, arg, format));
814
815 CASE_CFN_LOG10:
816 return (real_compare (GT_EXPR, arg, &dconst0)
817 && do_mpfr_arg1 (result, mpfr_log10, arg, format));
818
819 CASE_CFN_LOG1P:
820 return (real_compare (GT_EXPR, arg, &dconstm1)
821 && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
822
823 CASE_CFN_J0:
824 return do_mpfr_arg1 (result, mpfr_j0, arg, format);
825
826 CASE_CFN_J1:
827 return do_mpfr_arg1 (result, mpfr_j1, arg, format);
828
829 CASE_CFN_Y0:
830 return (real_compare (GT_EXPR, arg, &dconst0)
831 && do_mpfr_arg1 (result, mpfr_y0, arg, format));
832
833 CASE_CFN_Y1:
834 return (real_compare (GT_EXPR, arg, &dconst0)
835 && do_mpfr_arg1 (result, mpfr_y1, arg, format));
836
837 CASE_CFN_FLOOR:
838 CASE_CFN_FLOOR_FN:
839 if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
840 {
841 real_floor (result, format, arg);
842 return true;
843 }
844 return false;
845
846 CASE_CFN_CEIL:
847 CASE_CFN_CEIL_FN:
848 if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
849 {
850 real_ceil (result, format, arg);
851 return true;
852 }
853 return false;
854
855 CASE_CFN_TRUNC:
856 CASE_CFN_TRUNC_FN:
857 if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
858 {
859 real_trunc (result, format, arg);
860 return true;
861 }
862 return false;
863
864 CASE_CFN_ROUND:
865 CASE_CFN_ROUND_FN:
866 if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
867 {
868 real_round (result, format, arg);
869 return true;
870 }
871 return false;
872
873 CASE_CFN_ROUNDEVEN:
874 CASE_CFN_ROUNDEVEN_FN:
875 if (!REAL_VALUE_ISSIGNALING_NAN (*arg))
876 {
877 real_roundeven (result, format, arg);
878 return true;
879 }
880 return false;
881
882 CASE_CFN_LOGB:
883 return fold_const_logb (result, arg, format);
884
885 CASE_CFN_SIGNIFICAND:
886 return fold_const_significand (result, arg, format);
887
888 default:
889 return false;
890 }
891 }
892
893 /* Try to evaluate:
894
895 *RESULT = FN (*ARG)
896
897 where FORMAT is the format of ARG and PRECISION is the number of
898 significant bits in the result. Return true on success. */
899
900 static bool
901 fold_const_call_ss (wide_int *result, combined_fn fn,
902 const real_value *arg, unsigned int precision,
903 const real_format *format)
904 {
905 switch (fn)
906 {
907 CASE_CFN_SIGNBIT:
908 if (real_isneg (arg))
909 *result = wi::one (precision);
910 else
911 *result = wi::zero (precision);
912 return true;
913
914 CASE_CFN_ILOGB:
915 /* For ilogb we don't know FP_ILOGB0, so only handle normal values.
916 Proceed iff radix == 2. In GCC, normalized significands are in
917 the range [0.5, 1.0). We want the exponent as if they were
918 [1.0, 2.0) so get the exponent and subtract 1. */
919 if (arg->cl == rvc_normal && format->b == 2)
920 {
921 *result = wi::shwi (REAL_EXP (arg) - 1, precision);
922 return true;
923 }
924 return false;
925
926 CASE_CFN_ICEIL:
927 CASE_CFN_LCEIL:
928 CASE_CFN_LLCEIL:
929 return fold_const_conversion (result, real_ceil, arg,
930 precision, format);
931
932 CASE_CFN_LFLOOR:
933 CASE_CFN_IFLOOR:
934 CASE_CFN_LLFLOOR:
935 return fold_const_conversion (result, real_floor, arg,
936 precision, format);
937
938 CASE_CFN_IROUND:
939 CASE_CFN_LROUND:
940 CASE_CFN_LLROUND:
941 return fold_const_conversion (result, real_round, arg,
942 precision, format);
943
944 CASE_CFN_IRINT:
945 CASE_CFN_LRINT:
946 CASE_CFN_LLRINT:
947 /* Not yet folded to a constant. */
948 return false;
949
950 CASE_CFN_FINITE:
951 case CFN_BUILT_IN_FINITED32:
952 case CFN_BUILT_IN_FINITED64:
953 case CFN_BUILT_IN_FINITED128:
954 case CFN_BUILT_IN_ISFINITE:
955 *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
956 return true;
957
958 CASE_CFN_ISINF:
959 case CFN_BUILT_IN_ISINFD32:
960 case CFN_BUILT_IN_ISINFD64:
961 case CFN_BUILT_IN_ISINFD128:
962 if (real_isinf (arg))
963 *result = wi::shwi (arg->sign ? -1 : 1, precision);
964 else
965 *result = wi::shwi (0, precision);
966 return true;
967
968 CASE_CFN_ISNAN:
969 case CFN_BUILT_IN_ISNAND32:
970 case CFN_BUILT_IN_ISNAND64:
971 case CFN_BUILT_IN_ISNAND128:
972 *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
973 return true;
974
975 default:
976 return false;
977 }
978 }
979
980 /* Try to evaluate:
981
982 *RESULT = FN (ARG)
983
984 where ARG_TYPE is the type of ARG and PRECISION is the number of bits
985 in the result. Return true on success. */
986
987 static bool
988 fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
989 unsigned int precision, tree arg_type)
990 {
991 switch (fn)
992 {
993 CASE_CFN_FFS:
994 *result = wi::shwi (wi::ffs (arg), precision);
995 return true;
996
997 CASE_CFN_CLZ:
998 {
999 int tmp;
1000 if (wi::ne_p (arg, 0))
1001 tmp = wi::clz (arg);
1002 else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
1003 tmp))
1004 tmp = TYPE_PRECISION (arg_type);
1005 *result = wi::shwi (tmp, precision);
1006 return true;
1007 }
1008
1009 CASE_CFN_CTZ:
1010 {
1011 int tmp;
1012 if (wi::ne_p (arg, 0))
1013 tmp = wi::ctz (arg);
1014 else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
1015 tmp))
1016 tmp = TYPE_PRECISION (arg_type);
1017 *result = wi::shwi (tmp, precision);
1018 return true;
1019 }
1020
1021 CASE_CFN_CLRSB:
1022 *result = wi::shwi (wi::clrsb (arg), precision);
1023 return true;
1024
1025 CASE_CFN_POPCOUNT:
1026 *result = wi::shwi (wi::popcount (arg), precision);
1027 return true;
1028
1029 CASE_CFN_PARITY:
1030 *result = wi::shwi (wi::parity (arg), precision);
1031 return true;
1032
1033 case CFN_BUILT_IN_BSWAP16:
1034 case CFN_BUILT_IN_BSWAP32:
1035 case CFN_BUILT_IN_BSWAP64:
1036 case CFN_BUILT_IN_BSWAP128:
1037 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
1038 return true;
1039
1040 default:
1041 return false;
1042 }
1043 }
1044
1045 /* Try to evaluate:
1046
1047 RESULT = FN (*ARG)
1048
1049 where FORMAT is the format of ARG and of the real and imaginary parts
1050 of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively. Return
1051 true on success. */
1052
1053 static bool
1054 fold_const_call_cs (real_value *result_real, real_value *result_imag,
1055 combined_fn fn, const real_value *arg,
1056 const real_format *format)
1057 {
1058 switch (fn)
1059 {
1060 CASE_CFN_CEXPI:
1061 /* cexpi(x+yi) = cos(x)+sin(y)*i. */
1062 return do_mpfr_sincos (result_imag, result_real, arg, format);
1063
1064 default:
1065 return false;
1066 }
1067 }
1068
1069 /* Try to evaluate:
1070
1071 *RESULT = fn (ARG)
1072
1073 where FORMAT is the format of RESULT and of the real and imaginary parts
1074 of ARG, passed as ARG_REAL and ARG_IMAG respectively. Return true on
1075 success. */
1076
1077 static bool
1078 fold_const_call_sc (real_value *result, combined_fn fn,
1079 const real_value *arg_real, const real_value *arg_imag,
1080 const real_format *format)
1081 {
1082 switch (fn)
1083 {
1084 CASE_CFN_CABS:
1085 return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
1086
1087 default:
1088 return false;
1089 }
1090 }
1091
1092 /* Try to evaluate:
1093
1094 RESULT = fn (ARG)
1095
1096 where FORMAT is the format of the real and imaginary parts of RESULT
1097 (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
1098 Return true on success. */
1099
1100 static bool
1101 fold_const_call_cc (real_value *result_real, real_value *result_imag,
1102 combined_fn fn, const real_value *arg_real,
1103 const real_value *arg_imag, const real_format *format)
1104 {
1105 switch (fn)
1106 {
1107 CASE_CFN_CCOS:
1108 return do_mpc_arg1 (result_real, result_imag, mpc_cos,
1109 arg_real, arg_imag, format);
1110
1111 CASE_CFN_CCOSH:
1112 return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
1113 arg_real, arg_imag, format);
1114
1115 CASE_CFN_CPROJ:
1116 if (real_isinf (arg_real) || real_isinf (arg_imag))
1117 {
1118 real_inf (result_real);
1119 *result_imag = dconst0;
1120 result_imag->sign = arg_imag->sign;
1121 }
1122 else
1123 {
1124 *result_real = *arg_real;
1125 *result_imag = *arg_imag;
1126 }
1127 return true;
1128
1129 CASE_CFN_CSIN:
1130 return do_mpc_arg1 (result_real, result_imag, mpc_sin,
1131 arg_real, arg_imag, format);
1132
1133 CASE_CFN_CSINH:
1134 return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
1135 arg_real, arg_imag, format);
1136
1137 CASE_CFN_CTAN:
1138 return do_mpc_arg1 (result_real, result_imag, mpc_tan,
1139 arg_real, arg_imag, format);
1140
1141 CASE_CFN_CTANH:
1142 return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
1143 arg_real, arg_imag, format);
1144
1145 CASE_CFN_CLOG:
1146 return do_mpc_arg1 (result_real, result_imag, mpc_log,
1147 arg_real, arg_imag, format);
1148
1149 CASE_CFN_CSQRT:
1150 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
1151 arg_real, arg_imag, format);
1152
1153 CASE_CFN_CASIN:
1154 return do_mpc_arg1 (result_real, result_imag, mpc_asin,
1155 arg_real, arg_imag, format);
1156
1157 CASE_CFN_CACOS:
1158 return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1159 arg_real, arg_imag, format);
1160
1161 CASE_CFN_CATAN:
1162 return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1163 arg_real, arg_imag, format);
1164
1165 CASE_CFN_CASINH:
1166 return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1167 arg_real, arg_imag, format);
1168
1169 CASE_CFN_CACOSH:
1170 return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1171 arg_real, arg_imag, format);
1172
1173 CASE_CFN_CATANH:
1174 return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1175 arg_real, arg_imag, format);
1176
1177 CASE_CFN_CEXP:
1178 return do_mpc_arg1 (result_real, result_imag, mpc_exp,
1179 arg_real, arg_imag, format);
1180
1181 default:
1182 return false;
1183 }
1184 }
1185
1186 /* Subroutine of fold_const_call, with the same interface. Handle cases
1187 where the arguments and result are numerical. */
1188
1189 static tree
1190 fold_const_call_1 (combined_fn fn, tree type, tree arg)
1191 {
1192 machine_mode mode = TYPE_MODE (type);
1193 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1194
1195 if (integer_cst_p (arg))
1196 {
1197 if (SCALAR_INT_MODE_P (mode))
1198 {
1199 wide_int result;
1200 if (fold_const_call_ss (&result, fn, wi::to_wide (arg),
1201 TYPE_PRECISION (type), TREE_TYPE (arg)))
1202 return wide_int_to_tree (type, result);
1203 }
1204 return NULL_TREE;
1205 }
1206
1207 if (real_cst_p (arg))
1208 {
1209 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
1210 if (mode == arg_mode)
1211 {
1212 /* real -> real. */
1213 REAL_VALUE_TYPE result;
1214 if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
1215 REAL_MODE_FORMAT (mode)))
1216 return build_real (type, result);
1217 }
1218 else if (COMPLEX_MODE_P (mode)
1219 && GET_MODE_INNER (mode) == arg_mode)
1220 {
1221 /* real -> complex real. */
1222 REAL_VALUE_TYPE result_real, result_imag;
1223 if (fold_const_call_cs (&result_real, &result_imag, fn,
1224 TREE_REAL_CST_PTR (arg),
1225 REAL_MODE_FORMAT (arg_mode)))
1226 return build_complex (type,
1227 build_real (TREE_TYPE (type), result_real),
1228 build_real (TREE_TYPE (type), result_imag));
1229 }
1230 else if (INTEGRAL_TYPE_P (type))
1231 {
1232 /* real -> int. */
1233 wide_int result;
1234 if (fold_const_call_ss (&result, fn,
1235 TREE_REAL_CST_PTR (arg),
1236 TYPE_PRECISION (type),
1237 REAL_MODE_FORMAT (arg_mode)))
1238 return wide_int_to_tree (type, result);
1239 }
1240 return NULL_TREE;
1241 }
1242
1243 if (complex_cst_p (arg))
1244 {
1245 gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
1246 machine_mode inner_mode = GET_MODE_INNER (arg_mode);
1247 tree argr = TREE_REALPART (arg);
1248 tree argi = TREE_IMAGPART (arg);
1249 if (mode == arg_mode
1250 && real_cst_p (argr)
1251 && real_cst_p (argi))
1252 {
1253 /* complex real -> complex real. */
1254 REAL_VALUE_TYPE result_real, result_imag;
1255 if (fold_const_call_cc (&result_real, &result_imag, fn,
1256 TREE_REAL_CST_PTR (argr),
1257 TREE_REAL_CST_PTR (argi),
1258 REAL_MODE_FORMAT (inner_mode)))
1259 return build_complex (type,
1260 build_real (TREE_TYPE (type), result_real),
1261 build_real (TREE_TYPE (type), result_imag));
1262 }
1263 if (mode == inner_mode
1264 && real_cst_p (argr)
1265 && real_cst_p (argi))
1266 {
1267 /* complex real -> real. */
1268 REAL_VALUE_TYPE result;
1269 if (fold_const_call_sc (&result, fn,
1270 TREE_REAL_CST_PTR (argr),
1271 TREE_REAL_CST_PTR (argi),
1272 REAL_MODE_FORMAT (inner_mode)))
1273 return build_real (type, result);
1274 }
1275 return NULL_TREE;
1276 }
1277
1278 return NULL_TREE;
1279 }
1280
1281 /* Try to fold FN (ARG) to a constant. Return the constant on success,
1282 otherwise return null. TYPE is the type of the return value. */
1283
1284 tree
1285 fold_const_call (combined_fn fn, tree type, tree arg)
1286 {
1287 switch (fn)
1288 {
1289 case CFN_BUILT_IN_STRLEN:
1290 if (const char *str = c_getstr (arg))
1291 return build_int_cst (type, strlen (str));
1292 return NULL_TREE;
1293
1294 CASE_CFN_NAN:
1295 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
1296 case CFN_BUILT_IN_NAND32:
1297 case CFN_BUILT_IN_NAND64:
1298 case CFN_BUILT_IN_NAND128:
1299 return fold_const_builtin_nan (type, arg, true);
1300
1301 CASE_CFN_NANS:
1302 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
1303 case CFN_BUILT_IN_NANSD32:
1304 case CFN_BUILT_IN_NANSD64:
1305 case CFN_BUILT_IN_NANSD128:
1306 return fold_const_builtin_nan (type, arg, false);
1307
1308 case CFN_REDUC_PLUS:
1309 return fold_const_reduction (type, arg, PLUS_EXPR);
1310
1311 case CFN_REDUC_MAX:
1312 return fold_const_reduction (type, arg, MAX_EXPR);
1313
1314 case CFN_REDUC_MIN:
1315 return fold_const_reduction (type, arg, MIN_EXPR);
1316
1317 case CFN_REDUC_AND:
1318 return fold_const_reduction (type, arg, BIT_AND_EXPR);
1319
1320 case CFN_REDUC_IOR:
1321 return fold_const_reduction (type, arg, BIT_IOR_EXPR);
1322
1323 case CFN_REDUC_XOR:
1324 return fold_const_reduction (type, arg, BIT_XOR_EXPR);
1325
1326 case CFN_VEC_CONVERT:
1327 return fold_const_vec_convert (type, arg);
1328
1329 default:
1330 return fold_const_call_1 (fn, type, arg);
1331 }
1332 }
1333
1334 /* Fold a call to IFN_FOLD_LEFT_<CODE> (ARG0, ARG1), returning a value
1335 of type TYPE. */
1336
1337 static tree
1338 fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code)
1339 {
1340 if (TREE_CODE (arg1) != VECTOR_CST)
1341 return NULL_TREE;
1342
1343 unsigned HOST_WIDE_INT nelts;
1344 if (!VECTOR_CST_NELTS (arg1).is_constant (&nelts))
1345 return NULL_TREE;
1346
1347 for (unsigned HOST_WIDE_INT i = 0; i < nelts; i++)
1348 {
1349 arg0 = const_binop (code, type, arg0, VECTOR_CST_ELT (arg1, i));
1350 if (arg0 == NULL_TREE || !CONSTANT_CLASS_P (arg0))
1351 return NULL_TREE;
1352 }
1353 return arg0;
1354 }
1355
1356 /* Try to evaluate:
1357
1358 *RESULT = FN (*ARG0, *ARG1)
1359
1360 in format FORMAT. Return true on success. */
1361
1362 static bool
1363 fold_const_call_sss (real_value *result, combined_fn fn,
1364 const real_value *arg0, const real_value *arg1,
1365 const real_format *format)
1366 {
1367 switch (fn)
1368 {
1369 CASE_CFN_DREM:
1370 CASE_CFN_REMAINDER:
1371 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1372
1373 CASE_CFN_ATAN2:
1374 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1375
1376 CASE_CFN_FDIM:
1377 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1378
1379 CASE_CFN_HYPOT:
1380 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1381
1382 CASE_CFN_COPYSIGN:
1383 CASE_CFN_COPYSIGN_FN:
1384 *result = *arg0;
1385 real_copysign (result, arg1);
1386 return true;
1387
1388 CASE_CFN_FMIN:
1389 CASE_CFN_FMIN_FN:
1390 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1391
1392 CASE_CFN_FMAX:
1393 CASE_CFN_FMAX_FN:
1394 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1395
1396 CASE_CFN_POW:
1397 return fold_const_pow (result, arg0, arg1, format);
1398
1399 CASE_CFN_NEXTAFTER:
1400 CASE_CFN_NEXTTOWARD:
1401 return fold_const_nextafter (result, arg0, arg1, format);
1402
1403 default:
1404 return false;
1405 }
1406 }
1407
1408 /* Try to evaluate:
1409
1410 *RESULT = FN (*ARG0, ARG1)
1411
1412 where FORMAT is the format of *RESULT and *ARG0. Return true on
1413 success. */
1414
1415 static bool
1416 fold_const_call_sss (real_value *result, combined_fn fn,
1417 const real_value *arg0, const wide_int_ref &arg1,
1418 const real_format *format)
1419 {
1420 switch (fn)
1421 {
1422 CASE_CFN_LDEXP:
1423 return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1424
1425 CASE_CFN_SCALBN:
1426 CASE_CFN_SCALBLN:
1427 return (format->b == 2
1428 && fold_const_builtin_load_exponent (result, arg0, arg1,
1429 format));
1430
1431 CASE_CFN_POWI:
1432 /* Avoid the folding if flag_signaling_nans is on and
1433 operand is a signaling NaN. */
1434 if (!flag_unsafe_math_optimizations
1435 && flag_signaling_nans
1436 && REAL_VALUE_ISSIGNALING_NAN (*arg0))
1437 return false;
1438
1439 real_powi (result, format, arg0, arg1.to_shwi ());
1440 return true;
1441
1442 default:
1443 return false;
1444 }
1445 }
1446
1447 /* Try to evaluate:
1448
1449 *RESULT = FN (ARG0, *ARG1)
1450
1451 where FORMAT is the format of *RESULT and *ARG1. Return true on
1452 success. */
1453
1454 static bool
1455 fold_const_call_sss (real_value *result, combined_fn fn,
1456 const wide_int_ref &arg0, const real_value *arg1,
1457 const real_format *format)
1458 {
1459 switch (fn)
1460 {
1461 CASE_CFN_JN:
1462 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1463
1464 CASE_CFN_YN:
1465 return (real_compare (GT_EXPR, arg1, &dconst0)
1466 && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
1467
1468 default:
1469 return false;
1470 }
1471 }
1472
1473 /* Try to evaluate:
1474
1475 RESULT = fn (ARG0, ARG1)
1476
1477 where FORMAT is the format of the real and imaginary parts of RESULT
1478 (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
1479 and of ARG1 (ARG1_REAL and ARG1_IMAG). Return true on success. */
1480
1481 static bool
1482 fold_const_call_ccc (real_value *result_real, real_value *result_imag,
1483 combined_fn fn, const real_value *arg0_real,
1484 const real_value *arg0_imag, const real_value *arg1_real,
1485 const real_value *arg1_imag, const real_format *format)
1486 {
1487 switch (fn)
1488 {
1489 CASE_CFN_CPOW:
1490 return do_mpc_arg2 (result_real, result_imag, mpc_pow,
1491 arg0_real, arg0_imag, arg1_real, arg1_imag, format);
1492
1493 default:
1494 return false;
1495 }
1496 }
1497
1498 /* Subroutine of fold_const_call, with the same interface. Handle cases
1499 where the arguments and result are numerical. */
1500
1501 static tree
1502 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
1503 {
1504 machine_mode mode = TYPE_MODE (type);
1505 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1506 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1507
1508 if (mode == arg0_mode
1509 && real_cst_p (arg0)
1510 && real_cst_p (arg1))
1511 {
1512 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1513 REAL_VALUE_TYPE result;
1514 if (arg0_mode == arg1_mode)
1515 {
1516 /* real, real -> real. */
1517 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1518 TREE_REAL_CST_PTR (arg1),
1519 REAL_MODE_FORMAT (mode)))
1520 return build_real (type, result);
1521 }
1522 else if (arg1_mode == TYPE_MODE (long_double_type_node))
1523 switch (fn)
1524 {
1525 CASE_CFN_NEXTTOWARD:
1526 /* real, long double -> real. */
1527 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1528 TREE_REAL_CST_PTR (arg1),
1529 REAL_MODE_FORMAT (mode)))
1530 return build_real (type, result);
1531 break;
1532 default:
1533 break;
1534 }
1535 return NULL_TREE;
1536 }
1537
1538 if (real_cst_p (arg0)
1539 && integer_cst_p (arg1))
1540 {
1541 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1542 if (mode == arg0_mode)
1543 {
1544 /* real, int -> real. */
1545 REAL_VALUE_TYPE result;
1546 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1547 wi::to_wide (arg1),
1548 REAL_MODE_FORMAT (mode)))
1549 return build_real (type, result);
1550 }
1551 return NULL_TREE;
1552 }
1553
1554 if (integer_cst_p (arg0)
1555 && real_cst_p (arg1))
1556 {
1557 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
1558 if (mode == arg1_mode)
1559 {
1560 /* int, real -> real. */
1561 REAL_VALUE_TYPE result;
1562 if (fold_const_call_sss (&result, fn, wi::to_wide (arg0),
1563 TREE_REAL_CST_PTR (arg1),
1564 REAL_MODE_FORMAT (mode)))
1565 return build_real (type, result);
1566 }
1567 return NULL_TREE;
1568 }
1569
1570 if (arg0_mode == arg1_mode
1571 && complex_cst_p (arg0)
1572 && complex_cst_p (arg1))
1573 {
1574 gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
1575 machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
1576 tree arg0r = TREE_REALPART (arg0);
1577 tree arg0i = TREE_IMAGPART (arg0);
1578 tree arg1r = TREE_REALPART (arg1);
1579 tree arg1i = TREE_IMAGPART (arg1);
1580 if (mode == arg0_mode
1581 && real_cst_p (arg0r)
1582 && real_cst_p (arg0i)
1583 && real_cst_p (arg1r)
1584 && real_cst_p (arg1i))
1585 {
1586 /* complex real, complex real -> complex real. */
1587 REAL_VALUE_TYPE result_real, result_imag;
1588 if (fold_const_call_ccc (&result_real, &result_imag, fn,
1589 TREE_REAL_CST_PTR (arg0r),
1590 TREE_REAL_CST_PTR (arg0i),
1591 TREE_REAL_CST_PTR (arg1r),
1592 TREE_REAL_CST_PTR (arg1i),
1593 REAL_MODE_FORMAT (inner_mode)))
1594 return build_complex (type,
1595 build_real (TREE_TYPE (type), result_real),
1596 build_real (TREE_TYPE (type), result_imag));
1597 }
1598 return NULL_TREE;
1599 }
1600
1601 return NULL_TREE;
1602 }
1603
1604 /* Try to fold FN (ARG0, ARG1) to a constant. Return the constant on success,
1605 otherwise return null. TYPE is the type of the return value. */
1606
1607 tree
1608 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
1609 {
1610 const char *p0, *p1;
1611 char c;
1612 switch (fn)
1613 {
1614 case CFN_BUILT_IN_STRSPN:
1615 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1616 return build_int_cst (type, strspn (p0, p1));
1617 return NULL_TREE;
1618
1619 case CFN_BUILT_IN_STRCSPN:
1620 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1621 return build_int_cst (type, strcspn (p0, p1));
1622 return NULL_TREE;
1623
1624 case CFN_BUILT_IN_STRCMP:
1625 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1626 return build_cmp_result (type, strcmp (p0, p1));
1627 return NULL_TREE;
1628
1629 case CFN_BUILT_IN_STRCASECMP:
1630 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1631 {
1632 int r = strcmp (p0, p1);
1633 if (r == 0)
1634 return build_cmp_result (type, r);
1635 }
1636 return NULL_TREE;
1637
1638 case CFN_BUILT_IN_INDEX:
1639 case CFN_BUILT_IN_STRCHR:
1640 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1641 {
1642 const char *r = strchr (p0, c);
1643 if (r == NULL)
1644 return build_int_cst (type, 0);
1645 return fold_convert (type,
1646 fold_build_pointer_plus_hwi (arg0, r - p0));
1647 }
1648 return NULL_TREE;
1649
1650 case CFN_BUILT_IN_RINDEX:
1651 case CFN_BUILT_IN_STRRCHR:
1652 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1653 {
1654 const char *r = strrchr (p0, c);
1655 if (r == NULL)
1656 return build_int_cst (type, 0);
1657 return fold_convert (type,
1658 fold_build_pointer_plus_hwi (arg0, r - p0));
1659 }
1660 return NULL_TREE;
1661
1662 case CFN_BUILT_IN_STRSTR:
1663 if ((p1 = c_getstr (arg1)))
1664 {
1665 if ((p0 = c_getstr (arg0)))
1666 {
1667 const char *r = strstr (p0, p1);
1668 if (r == NULL)
1669 return build_int_cst (type, 0);
1670 return fold_convert (type,
1671 fold_build_pointer_plus_hwi (arg0, r - p0));
1672 }
1673 if (*p1 == '\0')
1674 return fold_convert (type, arg0);
1675 }
1676 return NULL_TREE;
1677
1678 case CFN_FOLD_LEFT_PLUS:
1679 return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR);
1680
1681 default:
1682 return fold_const_call_1 (fn, type, arg0, arg1);
1683 }
1684 }
1685
1686 /* Try to evaluate:
1687
1688 *RESULT = FN (*ARG0, *ARG1, *ARG2)
1689
1690 in format FORMAT. Return true on success. */
1691
1692 static bool
1693 fold_const_call_ssss (real_value *result, combined_fn fn,
1694 const real_value *arg0, const real_value *arg1,
1695 const real_value *arg2, const real_format *format)
1696 {
1697 switch (fn)
1698 {
1699 CASE_CFN_FMA:
1700 CASE_CFN_FMA_FN:
1701 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1702
1703 case CFN_FMS:
1704 {
1705 real_value new_arg2 = real_value_negate (arg2);
1706 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, &new_arg2, format);
1707 }
1708
1709 case CFN_FNMA:
1710 {
1711 real_value new_arg0 = real_value_negate (arg0);
1712 return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1, arg2, format);
1713 }
1714
1715 case CFN_FNMS:
1716 {
1717 real_value new_arg0 = real_value_negate (arg0);
1718 real_value new_arg2 = real_value_negate (arg2);
1719 return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1,
1720 &new_arg2, format);
1721 }
1722
1723 default:
1724 return false;
1725 }
1726 }
1727
1728 /* Subroutine of fold_const_call, with the same interface. Handle cases
1729 where the arguments and result are numerical. */
1730
1731 static tree
1732 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1733 {
1734 machine_mode mode = TYPE_MODE (type);
1735 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1736 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1737 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
1738
1739 if (arg0_mode == arg1_mode
1740 && arg0_mode == arg2_mode
1741 && real_cst_p (arg0)
1742 && real_cst_p (arg1)
1743 && real_cst_p (arg2))
1744 {
1745 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1746 if (mode == arg0_mode)
1747 {
1748 /* real, real, real -> real. */
1749 REAL_VALUE_TYPE result;
1750 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
1751 TREE_REAL_CST_PTR (arg1),
1752 TREE_REAL_CST_PTR (arg2),
1753 REAL_MODE_FORMAT (mode)))
1754 return build_real (type, result);
1755 }
1756 return NULL_TREE;
1757 }
1758
1759 return NULL_TREE;
1760 }
1761
1762 /* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on
1763 success, otherwise return null. TYPE is the type of the return value. */
1764
1765 tree
1766 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1767 {
1768 const char *p0, *p1;
1769 char c;
1770 unsigned HOST_WIDE_INT s0, s1;
1771 size_t s2 = 0;
1772 switch (fn)
1773 {
1774 case CFN_BUILT_IN_STRNCMP:
1775 if (!host_size_t_cst_p (arg2, &s2))
1776 return NULL_TREE;
1777 if (s2 == 0
1778 && !TREE_SIDE_EFFECTS (arg0)
1779 && !TREE_SIDE_EFFECTS (arg1))
1780 return build_int_cst (type, 0);
1781 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1782 return build_int_cst (type, strncmp (p0, p1, s2));
1783 return NULL_TREE;
1784
1785 case CFN_BUILT_IN_STRNCASECMP:
1786 if (!host_size_t_cst_p (arg2, &s2))
1787 return NULL_TREE;
1788 if (s2 == 0
1789 && !TREE_SIDE_EFFECTS (arg0)
1790 && !TREE_SIDE_EFFECTS (arg1))
1791 return build_int_cst (type, 0);
1792 else if ((p0 = c_getstr (arg0))
1793 && (p1 = c_getstr (arg1))
1794 && strncmp (p0, p1, s2) == 0)
1795 return build_int_cst (type, 0);
1796 return NULL_TREE;
1797
1798 case CFN_BUILT_IN_BCMP:
1799 case CFN_BUILT_IN_MEMCMP:
1800 if (!host_size_t_cst_p (arg2, &s2))
1801 return NULL_TREE;
1802 if (s2 == 0
1803 && !TREE_SIDE_EFFECTS (arg0)
1804 && !TREE_SIDE_EFFECTS (arg1))
1805 return build_int_cst (type, 0);
1806 if ((p0 = getbyterep (arg0, &s0))
1807 && (p1 = getbyterep (arg1, &s1))
1808 && s2 <= s0
1809 && s2 <= s1)
1810 return build_cmp_result (type, memcmp (p0, p1, s2));
1811 return NULL_TREE;
1812
1813 case CFN_BUILT_IN_MEMCHR:
1814 if (!host_size_t_cst_p (arg2, &s2))
1815 return NULL_TREE;
1816 if (s2 == 0
1817 && !TREE_SIDE_EFFECTS (arg0)
1818 && !TREE_SIDE_EFFECTS (arg1))
1819 return build_int_cst (type, 0);
1820 if ((p0 = getbyterep (arg0, &s0))
1821 && s2 <= s0
1822 && target_char_cst_p (arg1, &c))
1823 {
1824 const char *r = (const char *) memchr (p0, c, s2);
1825 if (r == NULL)
1826 return build_int_cst (type, 0);
1827 return fold_convert (type,
1828 fold_build_pointer_plus_hwi (arg0, r - p0));
1829 }
1830 return NULL_TREE;
1831
1832 case CFN_WHILE_ULT:
1833 {
1834 poly_uint64 parg0, parg1;
1835 if (poly_int_tree_p (arg0, &parg0) && poly_int_tree_p (arg1, &parg1))
1836 return fold_while_ult (type, parg0, parg1);
1837 return NULL_TREE;
1838 }
1839
1840 default:
1841 return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1842 }
1843 }