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

source code of gcc/fold-const-call.cc