]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fold-const-call.c
cmd/go: update mkalldocs.sh
[thirdparty/gcc.git] / gcc / fold-const-call.c
CommitLineData
5c1a2e63 1/* Constant folding for calls to built-in and internal functions.
85ec4feb 2 Copyright (C) 1988-2018 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
530/* Try to evaluate:
531
532 *RESULT = ldexp (*ARG0, ARG1)
533
534 in format FORMAT. Return true on success. */
535
536static bool
537fold_const_builtin_load_exponent (real_value *result, const real_value *arg0,
538 const wide_int_ref &arg1,
539 const real_format *format)
540{
541 /* Bound the maximum adjustment to twice the range of the
542 mode's valid exponents. Use abs to ensure the range is
543 positive as a sanity check. */
544 int max_exp_adj = 2 * labs (format->emax - format->emin);
545
546 /* The requested adjustment must be inside this range. This
547 is a preliminary cap to avoid things like overflow, we
548 may still fail to compute the result for other reasons. */
549 if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj))
550 return false;
551
5a00b0aa
SS
552 /* Don't perform operation if we honor signaling NaNs and
553 operand is a signaling NaN. */
554 if (!flag_unsafe_math_optimizations
555 && flag_signaling_nans
556 && REAL_VALUE_ISSIGNALING_NAN (*arg0))
557 return false;
558
5c1a2e63
RS
559 REAL_VALUE_TYPE initial_result;
560 real_ldexp (&initial_result, arg0, arg1.to_shwi ());
561
562 /* Ensure we didn't overflow. */
563 if (real_isinf (&initial_result))
564 return false;
565
566 /* Only proceed if the target mode can hold the
567 resulting value. */
568 *result = real_value_truncate (format, initial_result);
569 return real_equal (&initial_result, result);
570}
571
df838ef0
RS
572/* Fold a call to __builtin_nan or __builtin_nans with argument ARG and
573 return type TYPE. QUIET is true if a quiet rather than signalling
574 NaN is required. */
575
576static tree
577fold_const_builtin_nan (tree type, tree arg, bool quiet)
578{
579 REAL_VALUE_TYPE real;
580 const char *str = c_getstr (arg);
581 if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
582 return build_real (type, real);
583 return NULL_TREE;
584}
585
16d24520
RS
586/* Fold a call to IFN_REDUC_<CODE> (ARG), returning a value of type TYPE. */
587
588static tree
589fold_const_reduction (tree type, tree arg, tree_code code)
590{
928686b1
RS
591 unsigned HOST_WIDE_INT nelts;
592 if (TREE_CODE (arg) != VECTOR_CST
593 || !VECTOR_CST_NELTS (arg).is_constant (&nelts))
16d24520
RS
594 return NULL_TREE;
595
596 tree res = VECTOR_CST_ELT (arg, 0);
928686b1 597 for (unsigned HOST_WIDE_INT i = 1; i < nelts; i++)
16d24520
RS
598 {
599 res = const_binop (code, type, res, VECTOR_CST_ELT (arg, i));
600 if (res == NULL_TREE || !CONSTANT_CLASS_P (res))
601 return NULL_TREE;
602 }
603 return res;
604}
605
5c1a2e63
RS
606/* Try to evaluate:
607
608 *RESULT = FN (*ARG)
609
610 in format FORMAT. Return true on success. */
611
612static bool
d7ebef06 613fold_const_call_ss (real_value *result, combined_fn fn,
5c1a2e63
RS
614 const real_value *arg, const real_format *format)
615{
616 switch (fn)
617 {
d7ebef06 618 CASE_CFN_SQRT:
ee5fd23a 619 CASE_CFN_SQRT_FN:
5c1a2e63
RS
620 return (real_compare (GE_EXPR, arg, &dconst0)
621 && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
622
d7ebef06 623 CASE_CFN_CBRT:
5c1a2e63
RS
624 return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
625
d7ebef06 626 CASE_CFN_ASIN:
5c1a2e63
RS
627 return (real_compare (GE_EXPR, arg, &dconstm1)
628 && real_compare (LE_EXPR, arg, &dconst1)
629 && do_mpfr_arg1 (result, mpfr_asin, arg, format));
630
d7ebef06 631 CASE_CFN_ACOS:
5c1a2e63
RS
632 return (real_compare (GE_EXPR, arg, &dconstm1)
633 && real_compare (LE_EXPR, arg, &dconst1)
634 && do_mpfr_arg1 (result, mpfr_acos, arg, format));
635
d7ebef06 636 CASE_CFN_ATAN:
5c1a2e63
RS
637 return do_mpfr_arg1 (result, mpfr_atan, arg, format);
638
d7ebef06 639 CASE_CFN_ASINH:
5c1a2e63
RS
640 return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
641
d7ebef06 642 CASE_CFN_ACOSH:
5c1a2e63
RS
643 return (real_compare (GE_EXPR, arg, &dconst1)
644 && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
645
d7ebef06 646 CASE_CFN_ATANH:
5c1a2e63
RS
647 return (real_compare (GE_EXPR, arg, &dconstm1)
648 && real_compare (LE_EXPR, arg, &dconst1)
649 && do_mpfr_arg1 (result, mpfr_atanh, arg, format));
650
d7ebef06 651 CASE_CFN_SIN:
5c1a2e63
RS
652 return do_mpfr_arg1 (result, mpfr_sin, arg, format);
653
d7ebef06 654 CASE_CFN_COS:
5c1a2e63
RS
655 return do_mpfr_arg1 (result, mpfr_cos, arg, format);
656
d7ebef06 657 CASE_CFN_TAN:
5c1a2e63
RS
658 return do_mpfr_arg1 (result, mpfr_tan, arg, format);
659
d7ebef06 660 CASE_CFN_SINH:
5c1a2e63
RS
661 return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
662
d7ebef06 663 CASE_CFN_COSH:
5c1a2e63
RS
664 return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
665
d7ebef06 666 CASE_CFN_TANH:
5c1a2e63
RS
667 return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
668
d7ebef06 669 CASE_CFN_ERF:
5c1a2e63
RS
670 return do_mpfr_arg1 (result, mpfr_erf, arg, format);
671
d7ebef06 672 CASE_CFN_ERFC:
5c1a2e63
RS
673 return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
674
d7ebef06 675 CASE_CFN_TGAMMA:
5c1a2e63
RS
676 return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
677
d7ebef06 678 CASE_CFN_EXP:
5c1a2e63
RS
679 return do_mpfr_arg1 (result, mpfr_exp, arg, format);
680
d7ebef06 681 CASE_CFN_EXP2:
5c1a2e63
RS
682 return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
683
d7ebef06
RS
684 CASE_CFN_EXP10:
685 CASE_CFN_POW10:
5c1a2e63
RS
686 return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
687
d7ebef06 688 CASE_CFN_EXPM1:
5c1a2e63
RS
689 return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
690
d7ebef06 691 CASE_CFN_LOG:
5c1a2e63
RS
692 return (real_compare (GT_EXPR, arg, &dconst0)
693 && do_mpfr_arg1 (result, mpfr_log, arg, format));
694
d7ebef06 695 CASE_CFN_LOG2:
5c1a2e63
RS
696 return (real_compare (GT_EXPR, arg, &dconst0)
697 && do_mpfr_arg1 (result, mpfr_log2, arg, format));
698
d7ebef06 699 CASE_CFN_LOG10:
5c1a2e63
RS
700 return (real_compare (GT_EXPR, arg, &dconst0)
701 && do_mpfr_arg1 (result, mpfr_log10, arg, format));
702
d7ebef06 703 CASE_CFN_LOG1P:
5c1a2e63
RS
704 return (real_compare (GT_EXPR, arg, &dconstm1)
705 && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
706
d7ebef06 707 CASE_CFN_J0:
5c1a2e63
RS
708 return do_mpfr_arg1 (result, mpfr_j0, arg, format);
709
d7ebef06 710 CASE_CFN_J1:
5c1a2e63
RS
711 return do_mpfr_arg1 (result, mpfr_j1, arg, format);
712
d7ebef06 713 CASE_CFN_Y0:
5c1a2e63
RS
714 return (real_compare (GT_EXPR, arg, &dconst0)
715 && do_mpfr_arg1 (result, mpfr_y0, arg, format));
716
d7ebef06 717 CASE_CFN_Y1:
5c1a2e63
RS
718 return (real_compare (GT_EXPR, arg, &dconst0)
719 && do_mpfr_arg1 (result, mpfr_y1, arg, format));
720
d7ebef06 721 CASE_CFN_FLOOR:
c6cfa2bf 722 CASE_CFN_FLOOR_FN:
5c1a2e63
RS
723 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
724 {
725 real_floor (result, format, arg);
726 return true;
727 }
728 return false;
729
d7ebef06 730 CASE_CFN_CEIL:
c6cfa2bf 731 CASE_CFN_CEIL_FN:
5c1a2e63
RS
732 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
733 {
734 real_ceil (result, format, arg);
735 return true;
736 }
737 return false;
738
d7ebef06 739 CASE_CFN_TRUNC:
c6cfa2bf 740 CASE_CFN_TRUNC_FN:
5c1a2e63
RS
741 real_trunc (result, format, arg);
742 return true;
743
d7ebef06 744 CASE_CFN_ROUND:
c6cfa2bf 745 CASE_CFN_ROUND_FN:
5c1a2e63
RS
746 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
747 {
748 real_round (result, format, arg);
749 return true;
750 }
751 return false;
752
d7ebef06 753 CASE_CFN_LOGB:
5c1a2e63
RS
754 return fold_const_logb (result, arg, format);
755
d7ebef06 756 CASE_CFN_SIGNIFICAND:
5c1a2e63
RS
757 return fold_const_significand (result, arg, format);
758
759 default:
760 return false;
761 }
762}
763
764/* Try to evaluate:
765
766 *RESULT = FN (*ARG)
767
768 where FORMAT is the format of ARG and PRECISION is the number of
769 significant bits in the result. Return true on success. */
770
771static bool
d7ebef06 772fold_const_call_ss (wide_int *result, combined_fn fn,
5c1a2e63
RS
773 const real_value *arg, unsigned int precision,
774 const real_format *format)
775{
776 switch (fn)
777 {
d7ebef06 778 CASE_CFN_SIGNBIT:
5c1a2e63
RS
779 if (real_isneg (arg))
780 *result = wi::one (precision);
781 else
782 *result = wi::zero (precision);
783 return true;
784
d7ebef06 785 CASE_CFN_ILOGB:
5c1a2e63
RS
786 /* For ilogb we don't know FP_ILOGB0, so only handle normal values.
787 Proceed iff radix == 2. In GCC, normalized significands are in
788 the range [0.5, 1.0). We want the exponent as if they were
789 [1.0, 2.0) so get the exponent and subtract 1. */
790 if (arg->cl == rvc_normal && format->b == 2)
791 {
792 *result = wi::shwi (REAL_EXP (arg) - 1, precision);
793 return true;
794 }
795 return false;
796
d7ebef06
RS
797 CASE_CFN_ICEIL:
798 CASE_CFN_LCEIL:
799 CASE_CFN_LLCEIL:
5c1a2e63
RS
800 return fold_const_conversion (result, real_ceil, arg,
801 precision, format);
802
d7ebef06
RS
803 CASE_CFN_LFLOOR:
804 CASE_CFN_IFLOOR:
805 CASE_CFN_LLFLOOR:
5c1a2e63
RS
806 return fold_const_conversion (result, real_floor, arg,
807 precision, format);
808
d7ebef06
RS
809 CASE_CFN_IROUND:
810 CASE_CFN_LROUND:
811 CASE_CFN_LLROUND:
5c1a2e63
RS
812 return fold_const_conversion (result, real_round, arg,
813 precision, format);
814
d7ebef06
RS
815 CASE_CFN_IRINT:
816 CASE_CFN_LRINT:
817 CASE_CFN_LLRINT:
5c1a2e63
RS
818 /* Not yet folded to a constant. */
819 return false;
820
d7ebef06
RS
821 CASE_CFN_FINITE:
822 case CFN_BUILT_IN_FINITED32:
823 case CFN_BUILT_IN_FINITED64:
824 case CFN_BUILT_IN_FINITED128:
825 case CFN_BUILT_IN_ISFINITE:
2556a032
RS
826 *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
827 return true;
828
d7ebef06
RS
829 CASE_CFN_ISINF:
830 case CFN_BUILT_IN_ISINFD32:
831 case CFN_BUILT_IN_ISINFD64:
832 case CFN_BUILT_IN_ISINFD128:
2556a032
RS
833 if (real_isinf (arg))
834 *result = wi::shwi (arg->sign ? -1 : 1, precision);
835 else
836 *result = wi::shwi (0, precision);
837 return true;
838
d7ebef06
RS
839 CASE_CFN_ISNAN:
840 case CFN_BUILT_IN_ISNAND32:
841 case CFN_BUILT_IN_ISNAND64:
842 case CFN_BUILT_IN_ISNAND128:
2556a032
RS
843 *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
844 return true;
845
5c1a2e63
RS
846 default:
847 return false;
848 }
849}
850
db9bd5d5
RS
851/* Try to evaluate:
852
853 *RESULT = FN (ARG)
854
855 where ARG_TYPE is the type of ARG and PRECISION is the number of bits
856 in the result. Return true on success. */
857
858static bool
d7ebef06
RS
859fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
860 unsigned int precision, tree arg_type)
db9bd5d5
RS
861{
862 switch (fn)
863 {
d7ebef06 864 CASE_CFN_FFS:
db9bd5d5
RS
865 *result = wi::shwi (wi::ffs (arg), precision);
866 return true;
867
d7ebef06 868 CASE_CFN_CLZ:
db9bd5d5
RS
869 {
870 int tmp;
871 if (wi::ne_p (arg, 0))
872 tmp = wi::clz (arg);
7a504f33
RS
873 else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
874 tmp))
db9bd5d5
RS
875 tmp = TYPE_PRECISION (arg_type);
876 *result = wi::shwi (tmp, precision);
877 return true;
878 }
879
d7ebef06 880 CASE_CFN_CTZ:
db9bd5d5
RS
881 {
882 int tmp;
883 if (wi::ne_p (arg, 0))
884 tmp = wi::ctz (arg);
7a504f33
RS
885 else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
886 tmp))
db9bd5d5
RS
887 tmp = TYPE_PRECISION (arg_type);
888 *result = wi::shwi (tmp, precision);
889 return true;
890 }
891
d7ebef06 892 CASE_CFN_CLRSB:
db9bd5d5
RS
893 *result = wi::shwi (wi::clrsb (arg), precision);
894 return true;
895
d7ebef06 896 CASE_CFN_POPCOUNT:
db9bd5d5
RS
897 *result = wi::shwi (wi::popcount (arg), precision);
898 return true;
899
d7ebef06 900 CASE_CFN_PARITY:
db9bd5d5
RS
901 *result = wi::shwi (wi::parity (arg), precision);
902 return true;
903
d7ebef06
RS
904 case CFN_BUILT_IN_BSWAP16:
905 case CFN_BUILT_IN_BSWAP32:
906 case CFN_BUILT_IN_BSWAP64:
db9bd5d5
RS
907 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
908 return true;
909
910 default:
911 return false;
912 }
913}
914
5c1a2e63
RS
915/* Try to evaluate:
916
917 RESULT = FN (*ARG)
918
919 where FORMAT is the format of ARG and of the real and imaginary parts
920 of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively. Return
921 true on success. */
922
923static bool
924fold_const_call_cs (real_value *result_real, real_value *result_imag,
d7ebef06 925 combined_fn fn, const real_value *arg,
5c1a2e63
RS
926 const real_format *format)
927{
928 switch (fn)
929 {
d7ebef06 930 CASE_CFN_CEXPI:
5c1a2e63
RS
931 /* cexpi(x+yi) = cos(x)+sin(y)*i. */
932 return do_mpfr_sincos (result_imag, result_real, arg, format);
933
934 default:
935 return false;
936 }
937}
938
939/* Try to evaluate:
940
941 *RESULT = fn (ARG)
942
943 where FORMAT is the format of RESULT and of the real and imaginary parts
944 of ARG, passed as ARG_REAL and ARG_IMAG respectively. Return true on
945 success. */
946
947static bool
d7ebef06 948fold_const_call_sc (real_value *result, combined_fn fn,
5c1a2e63
RS
949 const real_value *arg_real, const real_value *arg_imag,
950 const real_format *format)
951{
952 switch (fn)
953 {
d7ebef06 954 CASE_CFN_CABS:
5c1a2e63
RS
955 return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
956
957 default:
958 return false;
959 }
960}
961
962/* Try to evaluate:
963
964 RESULT = fn (ARG)
965
966 where FORMAT is the format of the real and imaginary parts of RESULT
967 (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
968 Return true on success. */
969
970static bool
971fold_const_call_cc (real_value *result_real, real_value *result_imag,
d7ebef06 972 combined_fn fn, const real_value *arg_real,
5c1a2e63
RS
973 const real_value *arg_imag, const real_format *format)
974{
975 switch (fn)
976 {
d7ebef06 977 CASE_CFN_CCOS:
5c1a2e63
RS
978 return do_mpc_arg1 (result_real, result_imag, mpc_cos,
979 arg_real, arg_imag, format);
980
d7ebef06 981 CASE_CFN_CCOSH:
5c1a2e63
RS
982 return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
983 arg_real, arg_imag, format);
984
d7ebef06 985 CASE_CFN_CPROJ:
5c1a2e63
RS
986 if (real_isinf (arg_real) || real_isinf (arg_imag))
987 {
988 real_inf (result_real);
989 *result_imag = dconst0;
990 result_imag->sign = arg_imag->sign;
991 }
992 else
993 {
994 *result_real = *arg_real;
995 *result_imag = *arg_imag;
996 }
997 return true;
998
d7ebef06 999 CASE_CFN_CSIN:
5c1a2e63
RS
1000 return do_mpc_arg1 (result_real, result_imag, mpc_sin,
1001 arg_real, arg_imag, format);
1002
d7ebef06 1003 CASE_CFN_CSINH:
5c1a2e63
RS
1004 return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
1005 arg_real, arg_imag, format);
1006
d7ebef06 1007 CASE_CFN_CTAN:
5c1a2e63
RS
1008 return do_mpc_arg1 (result_real, result_imag, mpc_tan,
1009 arg_real, arg_imag, format);
1010
d7ebef06 1011 CASE_CFN_CTANH:
5c1a2e63
RS
1012 return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
1013 arg_real, arg_imag, format);
1014
d7ebef06 1015 CASE_CFN_CLOG:
5c1a2e63
RS
1016 return do_mpc_arg1 (result_real, result_imag, mpc_log,
1017 arg_real, arg_imag, format);
1018
d7ebef06 1019 CASE_CFN_CSQRT:
5c1a2e63
RS
1020 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
1021 arg_real, arg_imag, format);
1022
d7ebef06 1023 CASE_CFN_CASIN:
5c1a2e63
RS
1024 return do_mpc_arg1 (result_real, result_imag, mpc_asin,
1025 arg_real, arg_imag, format);
1026
d7ebef06 1027 CASE_CFN_CACOS:
5c1a2e63
RS
1028 return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1029 arg_real, arg_imag, format);
1030
d7ebef06 1031 CASE_CFN_CATAN:
5c1a2e63
RS
1032 return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1033 arg_real, arg_imag, format);
1034
d7ebef06 1035 CASE_CFN_CASINH:
5c1a2e63
RS
1036 return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1037 arg_real, arg_imag, format);
1038
d7ebef06 1039 CASE_CFN_CACOSH:
5c1a2e63
RS
1040 return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1041 arg_real, arg_imag, format);
1042
d7ebef06 1043 CASE_CFN_CATANH:
5c1a2e63
RS
1044 return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1045 arg_real, arg_imag, format);
1046
d7ebef06 1047 CASE_CFN_CEXP:
5c1a2e63
RS
1048 return do_mpc_arg1 (result_real, result_imag, mpc_exp,
1049 arg_real, arg_imag, format);
1050
1051 default:
1052 return false;
1053 }
1054}
1055
df838ef0
RS
1056/* Subroutine of fold_const_call, with the same interface. Handle cases
1057 where the arguments and result are numerical. */
5c1a2e63 1058
df838ef0 1059static tree
d7ebef06 1060fold_const_call_1 (combined_fn fn, tree type, tree arg)
5c1a2e63
RS
1061{
1062 machine_mode mode = TYPE_MODE (type);
1063 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1064
db9bd5d5
RS
1065 if (integer_cst_p (arg))
1066 {
1067 if (SCALAR_INT_MODE_P (mode))
1068 {
1069 wide_int result;
8e6cdc90
RS
1070 if (fold_const_call_ss (&result, fn, wi::to_wide (arg),
1071 TYPE_PRECISION (type), TREE_TYPE (arg)))
db9bd5d5
RS
1072 return wide_int_to_tree (type, result);
1073 }
1074 return NULL_TREE;
1075 }
1076
5c1a2e63
RS
1077 if (real_cst_p (arg))
1078 {
1079 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
1080 if (mode == arg_mode)
1081 {
1082 /* real -> real. */
1083 REAL_VALUE_TYPE result;
1084 if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
1085 REAL_MODE_FORMAT (mode)))
1086 return build_real (type, result);
1087 }
1088 else if (COMPLEX_MODE_P (mode)
1089 && GET_MODE_INNER (mode) == arg_mode)
1090 {
1091 /* real -> complex real. */
1092 REAL_VALUE_TYPE result_real, result_imag;
1093 if (fold_const_call_cs (&result_real, &result_imag, fn,
1094 TREE_REAL_CST_PTR (arg),
1095 REAL_MODE_FORMAT (arg_mode)))
1096 return build_complex (type,
1097 build_real (TREE_TYPE (type), result_real),
1098 build_real (TREE_TYPE (type), result_imag));
1099 }
1100 else if (INTEGRAL_TYPE_P (type))
1101 {
1102 /* real -> int. */
1103 wide_int result;
1104 if (fold_const_call_ss (&result, fn,
1105 TREE_REAL_CST_PTR (arg),
1106 TYPE_PRECISION (type),
1107 REAL_MODE_FORMAT (arg_mode)))
1108 return wide_int_to_tree (type, result);
1109 }
1110 return NULL_TREE;
1111 }
1112
1113 if (complex_cst_p (arg))
1114 {
1115 gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
1116 machine_mode inner_mode = GET_MODE_INNER (arg_mode);
1117 tree argr = TREE_REALPART (arg);
1118 tree argi = TREE_IMAGPART (arg);
1119 if (mode == arg_mode
1120 && real_cst_p (argr)
1121 && real_cst_p (argi))
1122 {
1123 /* complex real -> complex real. */
1124 REAL_VALUE_TYPE result_real, result_imag;
1125 if (fold_const_call_cc (&result_real, &result_imag, fn,
1126 TREE_REAL_CST_PTR (argr),
1127 TREE_REAL_CST_PTR (argi),
1128 REAL_MODE_FORMAT (inner_mode)))
1129 return build_complex (type,
1130 build_real (TREE_TYPE (type), result_real),
1131 build_real (TREE_TYPE (type), result_imag));
1132 }
1133 if (mode == inner_mode
1134 && real_cst_p (argr)
1135 && real_cst_p (argi))
1136 {
1137 /* complex real -> real. */
1138 REAL_VALUE_TYPE result;
1139 if (fold_const_call_sc (&result, fn,
1140 TREE_REAL_CST_PTR (argr),
1141 TREE_REAL_CST_PTR (argi),
1142 REAL_MODE_FORMAT (inner_mode)))
1143 return build_real (type, result);
1144 }
1145 return NULL_TREE;
1146 }
1147
1148 return NULL_TREE;
1149}
1150
df838ef0
RS
1151/* Try to fold FN (ARG) to a constant. Return the constant on success,
1152 otherwise return null. TYPE is the type of the return value. */
1153
1154tree
d7ebef06 1155fold_const_call (combined_fn fn, tree type, tree arg)
df838ef0
RS
1156{
1157 switch (fn)
1158 {
d7ebef06 1159 case CFN_BUILT_IN_STRLEN:
df838ef0
RS
1160 if (const char *str = c_getstr (arg))
1161 return build_int_cst (type, strlen (str));
1162 return NULL_TREE;
1163
d7ebef06 1164 CASE_CFN_NAN:
6dc198e3 1165 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
d7ebef06
RS
1166 case CFN_BUILT_IN_NAND32:
1167 case CFN_BUILT_IN_NAND64:
1168 case CFN_BUILT_IN_NAND128:
df838ef0
RS
1169 return fold_const_builtin_nan (type, arg, true);
1170
d7ebef06 1171 CASE_CFN_NANS:
6dc198e3 1172 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
df838ef0
RS
1173 return fold_const_builtin_nan (type, arg, false);
1174
16d24520
RS
1175 case CFN_REDUC_PLUS:
1176 return fold_const_reduction (type, arg, PLUS_EXPR);
1177
1178 case CFN_REDUC_MAX:
1179 return fold_const_reduction (type, arg, MAX_EXPR);
1180
1181 case CFN_REDUC_MIN:
1182 return fold_const_reduction (type, arg, MIN_EXPR);
1183
898f07b0
RS
1184 case CFN_REDUC_AND:
1185 return fold_const_reduction (type, arg, BIT_AND_EXPR);
1186
1187 case CFN_REDUC_IOR:
1188 return fold_const_reduction (type, arg, BIT_IOR_EXPR);
1189
1190 case CFN_REDUC_XOR:
1191 return fold_const_reduction (type, arg, BIT_XOR_EXPR);
1192
df838ef0
RS
1193 default:
1194 return fold_const_call_1 (fn, type, arg);
1195 }
1196}
1197
b781a135
RS
1198/* Fold a call to IFN_FOLD_LEFT_<CODE> (ARG0, ARG1), returning a value
1199 of type TYPE. */
1200
1201static tree
1202fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code)
1203{
1204 if (TREE_CODE (arg1) != VECTOR_CST)
1205 return NULL_TREE;
1206
1207 unsigned HOST_WIDE_INT nelts;
1208 if (!VECTOR_CST_NELTS (arg1).is_constant (&nelts))
1209 return NULL_TREE;
1210
1211 for (unsigned HOST_WIDE_INT i = 0; i < nelts; i++)
1212 {
1213 arg0 = const_binop (code, type, arg0, VECTOR_CST_ELT (arg1, i));
1214 if (arg0 == NULL_TREE || !CONSTANT_CLASS_P (arg0))
1215 return NULL_TREE;
1216 }
1217 return arg0;
1218}
1219
5c1a2e63
RS
1220/* Try to evaluate:
1221
1222 *RESULT = FN (*ARG0, *ARG1)
1223
1224 in format FORMAT. Return true on success. */
1225
1226static bool
d7ebef06 1227fold_const_call_sss (real_value *result, combined_fn fn,
5c1a2e63
RS
1228 const real_value *arg0, const real_value *arg1,
1229 const real_format *format)
1230{
1231 switch (fn)
1232 {
d7ebef06
RS
1233 CASE_CFN_DREM:
1234 CASE_CFN_REMAINDER:
5c1a2e63
RS
1235 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1236
d7ebef06 1237 CASE_CFN_ATAN2:
5c1a2e63
RS
1238 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1239
d7ebef06 1240 CASE_CFN_FDIM:
5c1a2e63
RS
1241 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1242
d7ebef06 1243 CASE_CFN_HYPOT:
5c1a2e63
RS
1244 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1245
d7ebef06 1246 CASE_CFN_COPYSIGN:
ee5fd23a 1247 CASE_CFN_COPYSIGN_FN:
5c1a2e63
RS
1248 *result = *arg0;
1249 real_copysign (result, arg1);
1250 return true;
1251
d7ebef06 1252 CASE_CFN_FMIN:
ee5fd23a 1253 CASE_CFN_FMIN_FN:
5c1a2e63
RS
1254 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1255
d7ebef06 1256 CASE_CFN_FMAX:
ee5fd23a 1257 CASE_CFN_FMAX_FN:
5c1a2e63
RS
1258 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1259
d7ebef06 1260 CASE_CFN_POW:
5c1a2e63
RS
1261 return fold_const_pow (result, arg0, arg1, format);
1262
1263 default:
1264 return false;
1265 }
1266}
1267
1268/* Try to evaluate:
1269
1270 *RESULT = FN (*ARG0, ARG1)
1271
1272 where FORMAT is the format of *RESULT and *ARG0. Return true on
1273 success. */
1274
1275static bool
d7ebef06 1276fold_const_call_sss (real_value *result, combined_fn fn,
5c1a2e63
RS
1277 const real_value *arg0, const wide_int_ref &arg1,
1278 const real_format *format)
1279{
1280 switch (fn)
1281 {
d7ebef06 1282 CASE_CFN_LDEXP:
5c1a2e63
RS
1283 return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1284
d7ebef06
RS
1285 CASE_CFN_SCALBN:
1286 CASE_CFN_SCALBLN:
5c1a2e63
RS
1287 return (format->b == 2
1288 && fold_const_builtin_load_exponent (result, arg0, arg1,
1289 format));
1290
d7ebef06 1291 CASE_CFN_POWI:
5a00b0aa
SS
1292 /* Avoid the folding if flag_signaling_nans is on and
1293 operand is a signaling NaN. */
1294 if (!flag_unsafe_math_optimizations
1295 && flag_signaling_nans
1296 && REAL_VALUE_ISSIGNALING_NAN (*arg0))
1297 return false;
1298
5c1a2e63
RS
1299 real_powi (result, format, arg0, arg1.to_shwi ());
1300 return true;
1301
1302 default:
1303 return false;
1304 }
1305}
1306
1307/* Try to evaluate:
1308
1309 *RESULT = FN (ARG0, *ARG1)
1310
1311 where FORMAT is the format of *RESULT and *ARG1. Return true on
1312 success. */
1313
1314static bool
d7ebef06 1315fold_const_call_sss (real_value *result, combined_fn fn,
5c1a2e63
RS
1316 const wide_int_ref &arg0, const real_value *arg1,
1317 const real_format *format)
1318{
1319 switch (fn)
1320 {
d7ebef06 1321 CASE_CFN_JN:
5c1a2e63
RS
1322 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1323
d7ebef06 1324 CASE_CFN_YN:
5c1a2e63
RS
1325 return (real_compare (GT_EXPR, arg1, &dconst0)
1326 && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
1327
1328 default:
1329 return false;
1330 }
1331}
1332
1333/* Try to evaluate:
1334
1335 RESULT = fn (ARG0, ARG1)
1336
1337 where FORMAT is the format of the real and imaginary parts of RESULT
1338 (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
1339 and of ARG1 (ARG1_REAL and ARG1_IMAG). Return true on success. */
1340
1341static bool
1342fold_const_call_ccc (real_value *result_real, real_value *result_imag,
d7ebef06 1343 combined_fn fn, const real_value *arg0_real,
5c1a2e63
RS
1344 const real_value *arg0_imag, const real_value *arg1_real,
1345 const real_value *arg1_imag, const real_format *format)
1346{
1347 switch (fn)
1348 {
d7ebef06 1349 CASE_CFN_CPOW:
5c1a2e63
RS
1350 return do_mpc_arg2 (result_real, result_imag, mpc_pow,
1351 arg0_real, arg0_imag, arg1_real, arg1_imag, format);
1352
1353 default:
1354 return false;
1355 }
1356}
1357
df838ef0
RS
1358/* Subroutine of fold_const_call, with the same interface. Handle cases
1359 where the arguments and result are numerical. */
5c1a2e63 1360
df838ef0 1361static tree
d7ebef06 1362fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
5c1a2e63
RS
1363{
1364 machine_mode mode = TYPE_MODE (type);
1365 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1366 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1367
1368 if (arg0_mode == arg1_mode
1369 && real_cst_p (arg0)
1370 && real_cst_p (arg1))
1371 {
1372 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1373 if (mode == arg0_mode)
1374 {
1375 /* real, real -> real. */
1376 REAL_VALUE_TYPE result;
1377 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1378 TREE_REAL_CST_PTR (arg1),
1379 REAL_MODE_FORMAT (mode)))
1380 return build_real (type, result);
1381 }
1382 return NULL_TREE;
1383 }
1384
1385 if (real_cst_p (arg0)
1386 && integer_cst_p (arg1))
1387 {
1388 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1389 if (mode == arg0_mode)
1390 {
1391 /* real, int -> real. */
1392 REAL_VALUE_TYPE result;
1393 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
8e6cdc90
RS
1394 wi::to_wide (arg1),
1395 REAL_MODE_FORMAT (mode)))
5c1a2e63
RS
1396 return build_real (type, result);
1397 }
1398 return NULL_TREE;
1399 }
1400
1401 if (integer_cst_p (arg0)
1402 && real_cst_p (arg1))
1403 {
1404 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
1405 if (mode == arg1_mode)
1406 {
1407 /* int, real -> real. */
1408 REAL_VALUE_TYPE result;
8e6cdc90 1409 if (fold_const_call_sss (&result, fn, wi::to_wide (arg0),
5c1a2e63
RS
1410 TREE_REAL_CST_PTR (arg1),
1411 REAL_MODE_FORMAT (mode)))
1412 return build_real (type, result);
1413 }
1414 return NULL_TREE;
1415 }
1416
1417 if (arg0_mode == arg1_mode
1418 && complex_cst_p (arg0)
1419 && complex_cst_p (arg1))
1420 {
1421 gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
1422 machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
1423 tree arg0r = TREE_REALPART (arg0);
1424 tree arg0i = TREE_IMAGPART (arg0);
1425 tree arg1r = TREE_REALPART (arg1);
1426 tree arg1i = TREE_IMAGPART (arg1);
1427 if (mode == arg0_mode
1428 && real_cst_p (arg0r)
1429 && real_cst_p (arg0i)
1430 && real_cst_p (arg1r)
1431 && real_cst_p (arg1i))
1432 {
1433 /* complex real, complex real -> complex real. */
1434 REAL_VALUE_TYPE result_real, result_imag;
1435 if (fold_const_call_ccc (&result_real, &result_imag, fn,
1436 TREE_REAL_CST_PTR (arg0r),
1437 TREE_REAL_CST_PTR (arg0i),
1438 TREE_REAL_CST_PTR (arg1r),
1439 TREE_REAL_CST_PTR (arg1i),
1440 REAL_MODE_FORMAT (inner_mode)))
1441 return build_complex (type,
1442 build_real (TREE_TYPE (type), result_real),
1443 build_real (TREE_TYPE (type), result_imag));
1444 }
1445 return NULL_TREE;
1446 }
1447
1448 return NULL_TREE;
1449}
1450
df838ef0
RS
1451/* Try to fold FN (ARG0, ARG1) to a constant. Return the constant on success,
1452 otherwise return null. TYPE is the type of the return value. */
1453
1454tree
d7ebef06 1455fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
df838ef0
RS
1456{
1457 const char *p0, *p1;
bf2d0849 1458 char c;
df838ef0
RS
1459 switch (fn)
1460 {
d7ebef06 1461 case CFN_BUILT_IN_STRSPN:
df838ef0
RS
1462 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1463 return build_int_cst (type, strspn (p0, p1));
1464 return NULL_TREE;
1465
d7ebef06 1466 case CFN_BUILT_IN_STRCSPN:
df838ef0
RS
1467 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1468 return build_int_cst (type, strcspn (p0, p1));
1469 return NULL_TREE;
1470
d7ebef06 1471 case CFN_BUILT_IN_STRCMP:
df838ef0
RS
1472 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1473 return build_cmp_result (type, strcmp (p0, p1));
1474 return NULL_TREE;
1475
a918bfbf
ML
1476 case CFN_BUILT_IN_STRCASECMP:
1477 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1478 {
1479 int r = strcmp (p0, p1);
1480 if (r == 0)
1481 return build_cmp_result (type, r);
1482 }
1483 return NULL_TREE;
1484
bf2d0849
JJ
1485 case CFN_BUILT_IN_INDEX:
1486 case CFN_BUILT_IN_STRCHR:
1487 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1488 {
1489 const char *r = strchr (p0, c);
1490 if (r == NULL)
1491 return build_int_cst (type, 0);
1492 return fold_convert (type,
1493 fold_build_pointer_plus_hwi (arg0, r - p0));
1494 }
1495 return NULL_TREE;
1496
1497 case CFN_BUILT_IN_RINDEX:
1498 case CFN_BUILT_IN_STRRCHR:
1499 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1500 {
1501 const char *r = strrchr (p0, c);
1502 if (r == NULL)
1503 return build_int_cst (type, 0);
1504 return fold_convert (type,
1505 fold_build_pointer_plus_hwi (arg0, r - p0));
1506 }
1507 return NULL_TREE;
1508
c8952930
JJ
1509 case CFN_BUILT_IN_STRSTR:
1510 if ((p1 = c_getstr (arg1)))
1511 {
1512 if ((p0 = c_getstr (arg0)))
1513 {
1514 const char *r = strstr (p0, p1);
1515 if (r == NULL)
1516 return build_int_cst (type, 0);
1517 return fold_convert (type,
1518 fold_build_pointer_plus_hwi (arg0, r - p0));
1519 }
1520 if (*p1 == '\0')
1521 return fold_convert (type, arg0);
1522 }
1523 return NULL_TREE;
1524
b781a135
RS
1525 case CFN_FOLD_LEFT_PLUS:
1526 return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR);
1527
df838ef0
RS
1528 default:
1529 return fold_const_call_1 (fn, type, arg0, arg1);
1530 }
1531}
1532
5c1a2e63
RS
1533/* Try to evaluate:
1534
1535 *RESULT = FN (*ARG0, *ARG1, *ARG2)
1536
1537 in format FORMAT. Return true on success. */
1538
1539static bool
d7ebef06 1540fold_const_call_ssss (real_value *result, combined_fn fn,
5c1a2e63
RS
1541 const real_value *arg0, const real_value *arg1,
1542 const real_value *arg2, const real_format *format)
1543{
1544 switch (fn)
1545 {
d7ebef06 1546 CASE_CFN_FMA:
ee5fd23a 1547 CASE_CFN_FMA_FN:
5c1a2e63
RS
1548 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1549
1550 default:
1551 return false;
1552 }
1553}
1554
df838ef0
RS
1555/* Subroutine of fold_const_call, with the same interface. Handle cases
1556 where the arguments and result are numerical. */
5c1a2e63 1557
df838ef0 1558static tree
d7ebef06 1559fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
5c1a2e63
RS
1560{
1561 machine_mode mode = TYPE_MODE (type);
1562 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1563 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1564 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
1565
1566 if (arg0_mode == arg1_mode
1567 && arg0_mode == arg2_mode
1568 && real_cst_p (arg0)
1569 && real_cst_p (arg1)
1570 && real_cst_p (arg2))
1571 {
1572 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1573 if (mode == arg0_mode)
1574 {
1575 /* real, real, real -> real. */
1576 REAL_VALUE_TYPE result;
1577 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
1578 TREE_REAL_CST_PTR (arg1),
1579 TREE_REAL_CST_PTR (arg2),
1580 REAL_MODE_FORMAT (mode)))
1581 return build_real (type, result);
1582 }
1583 return NULL_TREE;
1584 }
1585
1586 return NULL_TREE;
1587}
1588
df838ef0
RS
1589/* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on
1590 success, otherwise return null. TYPE is the type of the return value. */
1591
1592tree
d7ebef06 1593fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
df838ef0
RS
1594{
1595 const char *p0, *p1;
66972191 1596 char c;
302356da
ML
1597 unsigned HOST_WIDE_INT s0, s1;
1598 size_t s2 = 0;
df838ef0
RS
1599 switch (fn)
1600 {
d7ebef06 1601 case CFN_BUILT_IN_STRNCMP:
66972191 1602 if (!host_size_t_cst_p (arg2, &s2))
a918bfbf 1603 return NULL_TREE;
66972191
JJ
1604 if (s2 == 0
1605 && !TREE_SIDE_EFFECTS (arg0)
1606 && !TREE_SIDE_EFFECTS (arg1))
1607 return build_int_cst (type, 0);
1608 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1609 return build_int_cst (type, strncmp (p0, p1, s2));
1610 return NULL_TREE;
1611
a918bfbf 1612 case CFN_BUILT_IN_STRNCASECMP:
66972191 1613 if (!host_size_t_cst_p (arg2, &s2))
a918bfbf 1614 return NULL_TREE;
66972191
JJ
1615 if (s2 == 0
1616 && !TREE_SIDE_EFFECTS (arg0)
1617 && !TREE_SIDE_EFFECTS (arg1))
1618 return build_int_cst (type, 0);
1619 else if ((p0 = c_getstr (arg0))
1620 && (p1 = c_getstr (arg1))
1621 && strncmp (p0, p1, s2) == 0)
1622 return build_int_cst (type, 0);
1623 return NULL_TREE;
1624
d7ebef06
RS
1625 case CFN_BUILT_IN_BCMP:
1626 case CFN_BUILT_IN_MEMCMP:
66972191
JJ
1627 if (!host_size_t_cst_p (arg2, &s2))
1628 return NULL_TREE;
1629 if (s2 == 0
1630 && !TREE_SIDE_EFFECTS (arg0)
1631 && !TREE_SIDE_EFFECTS (arg1))
1632 return build_int_cst (type, 0);
68c93708
ML
1633 if ((p0 = c_getstr (arg0, &s0))
1634 && (p1 = c_getstr (arg1, &s1))
68c93708
ML
1635 && s2 <= s0
1636 && s2 <= s1)
df838ef0
RS
1637 return build_cmp_result (type, memcmp (p0, p1, s2));
1638 return NULL_TREE;
1639
66972191
JJ
1640 case CFN_BUILT_IN_MEMCHR:
1641 if (!host_size_t_cst_p (arg2, &s2))
1642 return NULL_TREE;
1643 if (s2 == 0
1644 && !TREE_SIDE_EFFECTS (arg0)
1645 && !TREE_SIDE_EFFECTS (arg1))
1646 return build_int_cst (type, 0);
1647 if ((p0 = c_getstr (arg0, &s0))
1648 && s2 <= s0
1649 && target_char_cst_p (arg1, &c))
1650 {
1651 const char *r = (const char *) memchr (p0, c, s2);
1652 if (r == NULL)
1653 return build_int_cst (type, 0);
1654 return fold_convert (type,
1655 fold_build_pointer_plus_hwi (arg0, r - p0));
1656 }
1657 return NULL_TREE;
1658
df838ef0
RS
1659 default:
1660 return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1661 }
1662}
1663
5c1a2e63
RS
1664/* Fold a fma operation with arguments ARG[012]. */
1665
1666tree
1667fold_fma (location_t, tree type, tree arg0, tree arg1, tree arg2)
1668{
1669 REAL_VALUE_TYPE result;
1670 if (real_cst_p (arg0)
1671 && real_cst_p (arg1)
1672 && real_cst_p (arg2)
1673 && do_mpfr_arg3 (&result, mpfr_fma, TREE_REAL_CST_PTR (arg0),
1674 TREE_REAL_CST_PTR (arg1), TREE_REAL_CST_PTR (arg2),
1675 REAL_MODE_FORMAT (TYPE_MODE (type))))
1676 return build_real (type, result);
1677
1678 return NULL_TREE;
1679}