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