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