1/* Constant folding for calls to built-in and internal functions.
2 Copyright (C) 1988-2017 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "realmpfr.h"
24#include "tree.h"
25#include "stor-layout.h"
26#include "options.h"
27#include "fold-const.h"
28#include "fold-const-call.h"
29#include "case-cfn-macros.h"
30#include "tm.h" /* For C[LT]Z_DEFINED_AT_ZERO. */
31#include "builtins.h"
32#include "gimple-expr.h"
33
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
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{
61 if (types_compatible_p (size_type_node, TREE_TYPE (t))
62 && integer_cst_p (t)
63 && (wi::min_precision (wi::to_wide (t), UNSIGNED)
64 <= sizeof (size_t) * CHAR_BIT))
65 {
66 *size_out = tree_to_uhwi (t);
67 return true;
68 }
69 return false;
70}
71
72/* RES is the result of a comparison in which < 0 means "less", 0 means
73 "equal" and > 0 means "more". Canonicalize it to -1, 0 or 1 and
74 return it in type TYPE. */
75
76tree
77build_cmp_result (tree type, int res)
78{
79 return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0);
80}
81
82/* M is the result of trying to constant-fold an expression (starting
83 with clear MPFR flags) and INEXACT says whether the result in M is
84 exact or inexact. Return true if M can be used as a constant-folded
85 result in format FORMAT, storing the value in *RESULT if so. */
86
87static bool
88do_mpfr_ckconv (real_value *result, mpfr_srcptr m, bool inexact,
89 const real_format *format)
90{
91 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
92 overflow/underflow occurred. If -frounding-math, proceed iff the
93 result of calling FUNC was exact. */
94 if (!mpfr_number_p (m)
95 || mpfr_overflow_p ()
96 || mpfr_underflow_p ()
97 || (flag_rounding_math && inexact))
98 return false;
99
100 REAL_VALUE_TYPE tmp;
101 real_from_mpfr (&tmp, m, format, 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);
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))))
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
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
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
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
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{
591 if (TREE_CODE (arg) != VECTOR_CST)
592 return NULL_TREE;
593
594 tree res = VECTOR_CST_ELT (arg, 0);
595 unsigned int nelts = VECTOR_CST_NELTS (arg);
596 for (unsigned int i = 1; i < nelts; i++)
597 {
598 res = const_binop (code, type, res, VECTOR_CST_ELT (arg, i));
599 if (res == NULL_TREE || !CONSTANT_CLASS_P (res))
600 return NULL_TREE;
601 }
602 return res;
603}
604
605/* Try to evaluate:
606
607 *RESULT = FN (*ARG)
608
609 in format FORMAT. Return true on success. */
610
611static bool
612fold_const_call_ss (real_value *result, combined_fn fn,
613 const real_value *arg, const real_format *format)
614{
615 switch (fn)
616 {
617 CASE_CFN_SQRT:
618 CASE_CFN_SQRT_FN:
619 return (real_compare (GE_EXPR, arg, &dconst0)
620 && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
621
622 CASE_CFN_CBRT:
623 return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
624
625 CASE_CFN_ASIN:
626 return (real_compare (GE_EXPR, arg, &dconstm1)
627 && real_compare (LE_EXPR, arg, &dconst1)
628 && do_mpfr_arg1 (result, mpfr_asin, arg, format));
629
630 CASE_CFN_ACOS:
631 return (real_compare (GE_EXPR, arg, &dconstm1)
632 && real_compare (LE_EXPR, arg, &dconst1)
633 && do_mpfr_arg1 (result, mpfr_acos, arg, format));
634
635 CASE_CFN_ATAN:
636 return do_mpfr_arg1 (result, mpfr_atan, arg, format);
637
638 CASE_CFN_ASINH:
639 return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
640
641 CASE_CFN_ACOSH:
642 return (real_compare (GE_EXPR, arg, &dconst1)
643 && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
644
645 CASE_CFN_ATANH:
646 return (real_compare (GE_EXPR, arg, &dconstm1)
647 && real_compare (LE_EXPR, arg, &dconst1)
648 && do_mpfr_arg1 (result, mpfr_atanh, arg, format));
649
650 CASE_CFN_SIN:
651 return do_mpfr_arg1 (result, mpfr_sin, arg, format);
652
653 CASE_CFN_COS:
654 return do_mpfr_arg1 (result, mpfr_cos, arg, format);
655
656 CASE_CFN_TAN:
657 return do_mpfr_arg1 (result, mpfr_tan, arg, format);
658
659 CASE_CFN_SINH:
660 return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
661
662 CASE_CFN_COSH:
663 return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
664
665 CASE_CFN_TANH:
666 return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
667
668 CASE_CFN_ERF:
669 return do_mpfr_arg1 (result, mpfr_erf, arg, format);
670
671 CASE_CFN_ERFC:
672 return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
673
674 CASE_CFN_TGAMMA:
675 return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
676
677 CASE_CFN_EXP:
678 return do_mpfr_arg1 (result, mpfr_exp, arg, format);
679
680 CASE_CFN_EXP2:
681 return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
682
683 CASE_CFN_EXP10:
684 CASE_CFN_POW10:
685 return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
686
687 CASE_CFN_EXPM1:
688 return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
689
690 CASE_CFN_LOG:
691 return (real_compare (GT_EXPR, arg, &dconst0)
692 && do_mpfr_arg1 (result, mpfr_log, arg, format));
693
694 CASE_CFN_LOG2:
695 return (real_compare (GT_EXPR, arg, &dconst0)
696 && do_mpfr_arg1 (result, mpfr_log2, arg, format));
697
698 CASE_CFN_LOG10:
699 return (real_compare (GT_EXPR, arg, &dconst0)
700 && do_mpfr_arg1 (result, mpfr_log10, arg, format));
701
702 CASE_CFN_LOG1P:
703 return (real_compare (GT_EXPR, arg, &dconstm1)
704 && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
705
706 CASE_CFN_J0:
707 return do_mpfr_arg1 (result, mpfr_j0, arg, format);
708
709 CASE_CFN_J1:
710 return do_mpfr_arg1 (result, mpfr_j1, arg, format);
711
712 CASE_CFN_Y0:
713 return (real_compare (GT_EXPR, arg, &dconst0)
714 && do_mpfr_arg1 (result, mpfr_y0, arg, format));
715
716 CASE_CFN_Y1:
717 return (real_compare (GT_EXPR, arg, &dconst0)
718 && do_mpfr_arg1 (result, mpfr_y1, arg, format));
719
720 CASE_CFN_FLOOR:
721 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
722 {
723 real_floor (result, format, arg);
724 return true;
725 }
726 return false;
727
728 CASE_CFN_CEIL:
729 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
730 {
731 real_ceil (result, format, arg);
732 return true;
733 }
734 return false;
735
736 CASE_CFN_TRUNC:
737 real_trunc (result, format, arg);
738 return true;
739
740 CASE_CFN_ROUND:
741 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
742 {
743 real_round (result, format, arg);
744 return true;
745 }
746 return false;
747
748 CASE_CFN_LOGB:
749 return fold_const_logb (result, arg, format);
750
751 CASE_CFN_SIGNIFICAND:
752 return fold_const_significand (result, arg, format);
753
754 default:
755 return false;
756 }
757}
758
759/* Try to evaluate:
760
761 *RESULT = FN (*ARG)
762
763 where FORMAT is the format of ARG and PRECISION is the number of
764 significant bits in the result. Return true on success. */
765
766static bool
767fold_const_call_ss (wide_int *result, combined_fn fn,
768 const real_value *arg, unsigned int precision,
769 const real_format *format)
770{
771 switch (fn)
772 {
773 CASE_CFN_SIGNBIT:
774 if (real_isneg (arg))
775 *result = wi::one (precision);
776 else
777 *result = wi::zero (precision);
778 return true;
779
780 CASE_CFN_ILOGB:
781 /* For ilogb we don't know FP_ILOGB0, so only handle normal values.
782 Proceed iff radix == 2. In GCC, normalized significands are in
783 the range [0.5, 1.0). We want the exponent as if they were
784 [1.0, 2.0) so get the exponent and subtract 1. */
785 if (arg->cl == rvc_normal && format->b == 2)
786 {
787 *result = wi::shwi (REAL_EXP (arg) - 1, precision);
788 return true;
789 }
790 return false;
791
792 CASE_CFN_ICEIL:
793 CASE_CFN_LCEIL:
794 CASE_CFN_LLCEIL:
795 return fold_const_conversion (result, real_ceil, arg,
796 precision, format);
797
798 CASE_CFN_LFLOOR:
799 CASE_CFN_IFLOOR:
800 CASE_CFN_LLFLOOR:
801 return fold_const_conversion (result, real_floor, arg,
802 precision, format);
803
804 CASE_CFN_IROUND:
805 CASE_CFN_LROUND:
806 CASE_CFN_LLROUND:
807 return fold_const_conversion (result, real_round, arg,
808 precision, format);
809
810 CASE_CFN_IRINT:
811 CASE_CFN_LRINT:
812 CASE_CFN_LLRINT:
813 /* Not yet folded to a constant. */
814 return false;
815
816 CASE_CFN_FINITE:
817 case CFN_BUILT_IN_FINITED32:
818 case CFN_BUILT_IN_FINITED64:
819 case CFN_BUILT_IN_FINITED128:
820 case CFN_BUILT_IN_ISFINITE:
821 *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
822 return true;
823
824 CASE_CFN_ISINF:
825 case CFN_BUILT_IN_ISINFD32:
826 case CFN_BUILT_IN_ISINFD64:
827 case CFN_BUILT_IN_ISINFD128:
828 if (real_isinf (arg))
829 *result = wi::shwi (arg->sign ? -1 : 1, precision);
830 else
831 *result = wi::shwi (0, precision);
832 return true;
833
834 CASE_CFN_ISNAN:
835 case CFN_BUILT_IN_ISNAND32:
836 case CFN_BUILT_IN_ISNAND64:
837 case CFN_BUILT_IN_ISNAND128:
838 *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
839 return true;
840
841 default:
842 return false;
843 }
844}
845
846/* Try to evaluate:
847
848 *RESULT = FN (ARG)
849
850 where ARG_TYPE is the type of ARG and PRECISION is the number of bits
851 in the result. Return true on success. */
852
853static bool
854fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
855 unsigned int precision, tree arg_type)
856{
857 switch (fn)
858 {
859 CASE_CFN_FFS:
860 *result = wi::shwi (wi::ffs (arg), precision);
861 return true;
862
863 CASE_CFN_CLZ:
864 {
865 int tmp;
866 if (wi::ne_p (arg, 0))
867 tmp = wi::clz (arg);
868 else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
869 tmp))
870 tmp = TYPE_PRECISION (arg_type);
871 *result = wi::shwi (tmp, precision);
872 return true;
873 }
874
875 CASE_CFN_CTZ:
876 {
877 int tmp;
878 if (wi::ne_p (arg, 0))
879 tmp = wi::ctz (arg);
880 else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
881 tmp))
882 tmp = TYPE_PRECISION (arg_type);
883 *result = wi::shwi (tmp, precision);
884 return true;
885 }
886
887 CASE_CFN_CLRSB:
888 *result = wi::shwi (wi::clrsb (arg), precision);
889 return true;
890
891 CASE_CFN_POPCOUNT:
892 *result = wi::shwi (wi::popcount (arg), precision);
893 return true;
894
895 CASE_CFN_PARITY:
896 *result = wi::shwi (wi::parity (arg), precision);
897 return true;
898
899 case CFN_BUILT_IN_BSWAP16:
900 case CFN_BUILT_IN_BSWAP32:
901 case CFN_BUILT_IN_BSWAP64:
902 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
903 return true;
904
905 default:
906 return false;
907 }
908}
909
910/* Try to evaluate:
911
912 RESULT = FN (*ARG)
913
914 where FORMAT is the format of ARG and of the real and imaginary parts
915 of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively. Return
916 true on success. */
917
918static bool
919fold_const_call_cs (real_value *result_real, real_value *result_imag,
920 combined_fn fn, const real_value *arg,
921 const real_format *format)
922{
923 switch (fn)
924 {
925 CASE_CFN_CEXPI:
926 /* cexpi(x+yi) = cos(x)+sin(y)*i. */
927 return do_mpfr_sincos (result_imag, result_real, arg, format);
928
929 default:
930 return false;
931 }
932}
933
934/* Try to evaluate:
935
936 *RESULT = fn (ARG)
937
938 where FORMAT is the format of RESULT and of the real and imaginary parts
939 of ARG, passed as ARG_REAL and ARG_IMAG respectively. Return true on
940 success. */
941
942static bool
943fold_const_call_sc (real_value *result, combined_fn fn,
944 const real_value *arg_real, const real_value *arg_imag,
945 const real_format *format)
946{
947 switch (fn)
948 {
949 CASE_CFN_CABS:
950 return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
951
952 default:
953 return false;
954 }
955}
956
957/* Try to evaluate:
958
959 RESULT = fn (ARG)
960
961 where FORMAT is the format of the real and imaginary parts of RESULT
962 (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
963 Return true on success. */
964
965static bool
966fold_const_call_cc (real_value *result_real, real_value *result_imag,
967 combined_fn fn, const real_value *arg_real,
968 const real_value *arg_imag, const real_format *format)
969{
970 switch (fn)
971 {
972 CASE_CFN_CCOS:
973 return do_mpc_arg1 (result_real, result_imag, mpc_cos,
974 arg_real, arg_imag, format);
975
976 CASE_CFN_CCOSH:
977 return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
978 arg_real, arg_imag, format);
979
980 CASE_CFN_CPROJ:
981 if (real_isinf (arg_real) || real_isinf (arg_imag))
982 {
983 real_inf (result_real);
984 *result_imag = dconst0;
985 result_imag->sign = arg_imag->sign;
986 }
987 else
988 {
989 *result_real = *arg_real;
990 *result_imag = *arg_imag;
991 }
992 return true;
993
994 CASE_CFN_CSIN:
995 return do_mpc_arg1 (result_real, result_imag, mpc_sin,
996 arg_real, arg_imag, format);
997
998 CASE_CFN_CSINH:
999 return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
1000 arg_real, arg_imag, format);
1001
1002 CASE_CFN_CTAN:
1003 return do_mpc_arg1 (result_real, result_imag, mpc_tan,
1004 arg_real, arg_imag, format);
1005
1006 CASE_CFN_CTANH:
1007 return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
1008 arg_real, arg_imag, format);
1009
1010 CASE_CFN_CLOG:
1011 return do_mpc_arg1 (result_real, result_imag, mpc_log,
1012 arg_real, arg_imag, format);
1013
1014 CASE_CFN_CSQRT:
1015 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
1016 arg_real, arg_imag, format);
1017
1018 CASE_CFN_CASIN:
1019 return do_mpc_arg1 (result_real, result_imag, mpc_asin,
1020 arg_real, arg_imag, format);
1021
1022 CASE_CFN_CACOS:
1023 return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1024 arg_real, arg_imag, format);
1025
1026 CASE_CFN_CATAN:
1027 return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1028 arg_real, arg_imag, format);
1029
1030 CASE_CFN_CASINH:
1031 return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1032 arg_real, arg_imag, format);
1033
1034 CASE_CFN_CACOSH:
1035 return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1036 arg_real, arg_imag, format);
1037
1038 CASE_CFN_CATANH:
1039 return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1040 arg_real, arg_imag, format);
1041
1042 CASE_CFN_CEXP:
1043 return do_mpc_arg1 (result_real, result_imag, mpc_exp,
1044 arg_real, arg_imag, format);
1045
1046 default:
1047 return false;
1048 }
1049}
1050
1051/* Subroutine of fold_const_call, with the same interface. Handle cases
1052 where the arguments and result are numerical. */
1053
1054static tree
1055fold_const_call_1 (combined_fn fn, tree type, tree arg)
1056{
1057 machine_mode mode = TYPE_MODE (type);
1058 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1059
1060 if (integer_cst_p (arg))
1061 {
1062 if (SCALAR_INT_MODE_P (mode))
1063 {
1064 wide_int result;
1065 if (fold_const_call_ss (&result, fn, wi::to_wide (arg),
1066 TYPE_PRECISION (type), TREE_TYPE (arg)))
1067 return wide_int_to_tree (type, result);
1068 }
1069 return NULL_TREE;
1070 }
1071
1072 if (real_cst_p (arg))
1073 {
1074 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
1075 if (mode == arg_mode)
1076 {
1077 /* real -> real. */
1078 REAL_VALUE_TYPE result;
1079 if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
1080 REAL_MODE_FORMAT (mode)))
1081 return build_real (type, result);
1082 }
1083 else if (COMPLEX_MODE_P (mode)
1084 && GET_MODE_INNER (mode) == arg_mode)
1085 {
1086 /* real -> complex real. */
1087 REAL_VALUE_TYPE result_real, result_imag;
1088 if (fold_const_call_cs (&result_real, &result_imag, fn,
1089 TREE_REAL_CST_PTR (arg),
1090 REAL_MODE_FORMAT (arg_mode)))
1091 return build_complex (type,
1092 build_real (TREE_TYPE (type), result_real),
1093 build_real (TREE_TYPE (type), result_imag));
1094 }
1095 else if (INTEGRAL_TYPE_P (type))
1096 {
1097 /* real -> int. */
1098 wide_int result;
1099 if (fold_const_call_ss (&result, fn,
1100 TREE_REAL_CST_PTR (arg),
1101 TYPE_PRECISION (type),
1102 REAL_MODE_FORMAT (arg_mode)))
1103 return wide_int_to_tree (type, result);
1104 }
1105 return NULL_TREE;
1106 }
1107
1108 if (complex_cst_p (arg))
1109 {
1110 gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
1111 machine_mode inner_mode = GET_MODE_INNER (arg_mode);
1112 tree argr = TREE_REALPART (arg);
1113 tree argi = TREE_IMAGPART (arg);
1114 if (mode == arg_mode
1115 && real_cst_p (argr)
1116 && real_cst_p (argi))
1117 {
1118 /* complex real -> complex real. */
1119 REAL_VALUE_TYPE result_real, result_imag;
1120 if (fold_const_call_cc (&result_real, &result_imag, fn,
1121 TREE_REAL_CST_PTR (argr),
1122 TREE_REAL_CST_PTR (argi),
1123 REAL_MODE_FORMAT (inner_mode)))
1124 return build_complex (type,
1125 build_real (TREE_TYPE (type), result_real),
1126 build_real (TREE_TYPE (type), result_imag));
1127 }
1128 if (mode == inner_mode
1129 && real_cst_p (argr)
1130 && real_cst_p (argi))
1131 {
1132 /* complex real -> real. */
1133 REAL_VALUE_TYPE result;
1134 if (fold_const_call_sc (&result, fn,
1135 TREE_REAL_CST_PTR (argr),
1136 TREE_REAL_CST_PTR (argi),
1137 REAL_MODE_FORMAT (inner_mode)))
1138 return build_real (type, result);
1139 }
1140 return NULL_TREE;
1141 }
1142
1143 return NULL_TREE;
1144}
1145
1146/* Try to fold FN (ARG) to a constant. Return the constant on success,
1147 otherwise return null. TYPE is the type of the return value. */
1148
1149tree
1150fold_const_call (combined_fn fn, tree type, tree arg)
1151{
1152 switch (fn)
1153 {
1154 case CFN_BUILT_IN_STRLEN:
1155 if (const char *str = c_getstr (arg))
1156 return build_int_cst (type, strlen (str));
1157 return NULL_TREE;
1158
1159 CASE_CFN_NAN:
1160 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
1161 case CFN_BUILT_IN_NAND32:
1162 case CFN_BUILT_IN_NAND64:
1163 case CFN_BUILT_IN_NAND128:
1164 return fold_const_builtin_nan (type, arg, true);
1165
1166 CASE_CFN_NANS:
1167 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
1168 return fold_const_builtin_nan (type, arg, false);
1169
1170 case CFN_REDUC_PLUS:
1171 return fold_const_reduction (type, arg, PLUS_EXPR);
1172
1173 case CFN_REDUC_MAX:
1174 return fold_const_reduction (type, arg, MAX_EXPR);
1175
1176 case CFN_REDUC_MIN:
1177 return fold_const_reduction (type, arg, MIN_EXPR);
1178
1179 default:
1180 return fold_const_call_1 (fn, type, arg);
1181 }
1182}
1183
1184/* Try to evaluate:
1185
1186 *RESULT = FN (*ARG0, *ARG1)
1187
1188 in format FORMAT. Return true on success. */
1189
1190static bool
1191fold_const_call_sss (real_value *result, combined_fn fn,
1192 const real_value *arg0, const real_value *arg1,
1193 const real_format *format)
1194{
1195 switch (fn)
1196 {
1197 CASE_CFN_DREM:
1198 CASE_CFN_REMAINDER:
1199 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1200
1201 CASE_CFN_ATAN2:
1202 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1203
1204 CASE_CFN_FDIM:
1205 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1206
1207 CASE_CFN_HYPOT:
1208 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1209
1210 CASE_CFN_COPYSIGN:
1211 CASE_CFN_COPYSIGN_FN:
1212 *result = *arg0;
1213 real_copysign (result, arg1);
1214 return true;
1215
1216 CASE_CFN_FMIN:
1217 CASE_CFN_FMIN_FN:
1218 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1219
1220 CASE_CFN_FMAX:
1221 CASE_CFN_FMAX_FN:
1222 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1223
1224 CASE_CFN_POW:
1225 return fold_const_pow (result, arg0, arg1, format);
1226
1227 default:
1228 return false;
1229 }
1230}
1231
1232/* Try to evaluate:
1233
1234 *RESULT = FN (*ARG0, ARG1)
1235
1236 where FORMAT is the format of *RESULT and *ARG0. Return true on
1237 success. */
1238
1239static bool
1240fold_const_call_sss (real_value *result, combined_fn fn,
1241 const real_value *arg0, const wide_int_ref &arg1,
1242 const real_format *format)
1243{
1244 switch (fn)
1245 {
1246 CASE_CFN_LDEXP:
1247 return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1248
1249 CASE_CFN_SCALBN:
1250 CASE_CFN_SCALBLN:
1251 return (format->b == 2
1252 && fold_const_builtin_load_exponent (result, arg0, arg1,
1253 format));
1254
1255 CASE_CFN_POWI:
1256 /* Avoid the folding if flag_signaling_nans is on and
1257 operand is a signaling NaN. */
1258 if (!flag_unsafe_math_optimizations
1259 && flag_signaling_nans
1260 && REAL_VALUE_ISSIGNALING_NAN (*arg0))
1261 return false;
1262
1263 real_powi (result, format, arg0, arg1.to_shwi ());
1264 return true;
1265
1266 default:
1267 return false;
1268 }
1269}
1270
1271/* Try to evaluate:
1272
1273 *RESULT = FN (ARG0, *ARG1)
1274
1275 where FORMAT is the format of *RESULT and *ARG1. Return true on
1276 success. */
1277
1278static bool
1279fold_const_call_sss (real_value *result, combined_fn fn,
1280 const wide_int_ref &arg0, const real_value *arg1,
1281 const real_format *format)
1282{
1283 switch (fn)
1284 {
1285 CASE_CFN_JN:
1286 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1287
1288 CASE_CFN_YN:
1289 return (real_compare (GT_EXPR, arg1, &dconst0)
1290 && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
1291
1292 default:
1293 return false;
1294 }
1295}
1296
1297/* Try to evaluate:
1298
1299 RESULT = fn (ARG0, ARG1)
1300
1301 where FORMAT is the format of the real and imaginary parts of RESULT
1302 (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
1303 and of ARG1 (ARG1_REAL and ARG1_IMAG). Return true on success. */
1304
1305static bool
1306fold_const_call_ccc (real_value *result_real, real_value *result_imag,
1307 combined_fn fn, const real_value *arg0_real,
1308 const real_value *arg0_imag, const real_value *arg1_real,
1309 const real_value *arg1_imag, const real_format *format)
1310{
1311 switch (fn)
1312 {
1313 CASE_CFN_CPOW:
1314 return do_mpc_arg2 (result_real, result_imag, mpc_pow,
1315 arg0_real, arg0_imag, arg1_real, arg1_imag, format);
1316
1317 default:
1318 return false;
1319 }
1320}
1321
1322/* Subroutine of fold_const_call, with the same interface. Handle cases
1323 where the arguments and result are numerical. */
1324
1325static tree
1326fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
1327{
1328 machine_mode mode = TYPE_MODE (type);
1329 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1330 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1331
1332 if (arg0_mode == arg1_mode
1333 && real_cst_p (arg0)
1334 && real_cst_p (arg1))
1335 {
1336 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1337 if (mode == arg0_mode)
1338 {
1339 /* real, real -> real. */
1340 REAL_VALUE_TYPE result;
1341 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1342 TREE_REAL_CST_PTR (arg1),
1343 REAL_MODE_FORMAT (mode)))
1344 return build_real (type, result);
1345 }
1346 return NULL_TREE;
1347 }
1348
1349 if (real_cst_p (arg0)
1350 && integer_cst_p (arg1))
1351 {
1352 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1353 if (mode == arg0_mode)
1354 {
1355 /* real, int -> real. */
1356 REAL_VALUE_TYPE result;
1357 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1358 wi::to_wide (arg1),
1359 REAL_MODE_FORMAT (mode)))
1360 return build_real (type, result);
1361 }
1362 return NULL_TREE;
1363 }
1364
1365 if (integer_cst_p (arg0)
1366 && real_cst_p (arg1))
1367 {
1368 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
1369 if (mode == arg1_mode)
1370 {
1371 /* int, real -> real. */
1372 REAL_VALUE_TYPE result;
1373 if (fold_const_call_sss (&result, fn, wi::to_wide (arg0),
1374 TREE_REAL_CST_PTR (arg1),
1375 REAL_MODE_FORMAT (mode)))
1376 return build_real (type, result);
1377 }
1378 return NULL_TREE;
1379 }
1380
1381 if (arg0_mode == arg1_mode
1382 && complex_cst_p (arg0)
1383 && complex_cst_p (arg1))
1384 {
1385 gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
1386 machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
1387 tree arg0r = TREE_REALPART (arg0);
1388 tree arg0i = TREE_IMAGPART (arg0);
1389 tree arg1r = TREE_REALPART (arg1);
1390 tree arg1i = TREE_IMAGPART (arg1);
1391 if (mode == arg0_mode
1392 && real_cst_p (arg0r)
1393 && real_cst_p (arg0i)
1394 && real_cst_p (arg1r)
1395 && real_cst_p (arg1i))
1396 {
1397 /* complex real, complex real -> complex real. */
1398 REAL_VALUE_TYPE result_real, result_imag;
1399 if (fold_const_call_ccc (&result_real, &result_imag, fn,
1400 TREE_REAL_CST_PTR (arg0r),
1401 TREE_REAL_CST_PTR (arg0i),
1402 TREE_REAL_CST_PTR (arg1r),
1403 TREE_REAL_CST_PTR (arg1i),
1404 REAL_MODE_FORMAT (inner_mode)))
1405 return build_complex (type,
1406 build_real (TREE_TYPE (type), result_real),
1407 build_real (TREE_TYPE (type), result_imag));
1408 }
1409 return NULL_TREE;
1410 }
1411
1412 return NULL_TREE;
1413}
1414
1415/* Try to fold FN (ARG0, ARG1) to a constant. Return the constant on success,
1416 otherwise return null. TYPE is the type of the return value. */
1417
1418tree
1419fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
1420{
1421 const char *p0, *p1;
1422 char c;
1423 switch (fn)
1424 {
1425 case CFN_BUILT_IN_STRSPN:
1426 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1427 return build_int_cst (type, strspn (p0, p1));
1428 return NULL_TREE;
1429
1430 case CFN_BUILT_IN_STRCSPN:
1431 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1432 return build_int_cst (type, strcspn (p0, p1));
1433 return NULL_TREE;
1434
1435 case CFN_BUILT_IN_STRCMP:
1436 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1437 return build_cmp_result (type, strcmp (p0, p1));
1438 return NULL_TREE;
1439
1440 case CFN_BUILT_IN_STRCASECMP:
1441 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1442 {
1443 int r = strcmp (p0, p1);
1444 if (r == 0)
1445 return build_cmp_result (type, r);
1446 }
1447 return NULL_TREE;
1448
1449 case CFN_BUILT_IN_INDEX:
1450 case CFN_BUILT_IN_STRCHR:
1451 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1452 {
1453 const char *r = strchr (p0, c);
1454 if (r == NULL)
1455 return build_int_cst (type, 0);
1456 return fold_convert (type,
1457 fold_build_pointer_plus_hwi (arg0, r - p0));
1458 }
1459 return NULL_TREE;
1460
1461 case CFN_BUILT_IN_RINDEX:
1462 case CFN_BUILT_IN_STRRCHR:
1463 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1464 {
1465 const char *r = strrchr (p0, c);
1466 if (r == NULL)
1467 return build_int_cst (type, 0);
1468 return fold_convert (type,
1469 fold_build_pointer_plus_hwi (arg0, r - p0));
1470 }
1471 return NULL_TREE;
1472
1473 case CFN_BUILT_IN_STRSTR:
1474 if ((p1 = c_getstr (arg1)))
1475 {
1476 if ((p0 = c_getstr (arg0)))
1477 {
1478 const char *r = strstr (p0, p1);
1479 if (r == NULL)
1480 return build_int_cst (type, 0);
1481 return fold_convert (type,
1482 fold_build_pointer_plus_hwi (arg0, r - p0));
1483 }
1484 if (*p1 == '\0')
1485 return fold_convert (type, arg0);
1486 }
1487 return NULL_TREE;
1488
1489 default:
1490 return fold_const_call_1 (fn, type, arg0, arg1);
1491 }
1492}
1493
1494/* Try to evaluate:
1495
1496 *RESULT = FN (*ARG0, *ARG1, *ARG2)
1497
1498 in format FORMAT. Return true on success. */
1499
1500static bool
1501fold_const_call_ssss (real_value *result, combined_fn fn,
1502 const real_value *arg0, const real_value *arg1,
1503 const real_value *arg2, const real_format *format)
1504{
1505 switch (fn)
1506 {
1507 CASE_CFN_FMA:
1508 CASE_CFN_FMA_FN:
1509 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1510
1511 default:
1512 return false;
1513 }
1514}
1515
1516/* Subroutine of fold_const_call, with the same interface. Handle cases
1517 where the arguments and result are numerical. */
1518
1519static tree
1520fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1521{
1522 machine_mode mode = TYPE_MODE (type);
1523 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1524 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1525 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
1526
1527 if (arg0_mode == arg1_mode
1528 && arg0_mode == arg2_mode
1529 && real_cst_p (arg0)
1530 && real_cst_p (arg1)
1531 && real_cst_p (arg2))
1532 {
1533 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1534 if (mode == arg0_mode)
1535 {
1536 /* real, real, real -> real. */
1537 REAL_VALUE_TYPE result;
1538 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
1539 TREE_REAL_CST_PTR (arg1),
1540 TREE_REAL_CST_PTR (arg2),
1541 REAL_MODE_FORMAT (mode)))
1542 return build_real (type, result);
1543 }
1544 return NULL_TREE;
1545 }
1546
1547 return NULL_TREE;
1548}
1549
1550/* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on
1551 success, otherwise return null. TYPE is the type of the return value. */
1552
1553tree
1554fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1555{
1556 const char *p0, *p1;
1557 char c;
1558 unsigned HOST_WIDE_INT s0, s1;
1559 size_t s2 = 0;
1560 switch (fn)
1561 {
1562 case CFN_BUILT_IN_STRNCMP:
1563 if (!host_size_t_cst_p (arg2, &s2))
1564 return NULL_TREE;
1565 if (s2 == 0
1566 && !TREE_SIDE_EFFECTS (arg0)
1567 && !TREE_SIDE_EFFECTS (arg1))
1568 return build_int_cst (type, 0);
1569 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1570 return build_int_cst (type, strncmp (p0, p1, s2));
1571 return NULL_TREE;
1572
1573 case CFN_BUILT_IN_STRNCASECMP:
1574 if (!host_size_t_cst_p (arg2, &s2))
1575 return NULL_TREE;
1576 if (s2 == 0
1577 && !TREE_SIDE_EFFECTS (arg0)
1578 && !TREE_SIDE_EFFECTS (arg1))
1579 return build_int_cst (type, 0);
1580 else if ((p0 = c_getstr (arg0))
1581 && (p1 = c_getstr (arg1))
1582 && strncmp (p0, p1, s2) == 0)
1583 return build_int_cst (type, 0);
1584 return NULL_TREE;
1585
1586 case CFN_BUILT_IN_BCMP:
1587 case CFN_BUILT_IN_MEMCMP:
1588 if (!host_size_t_cst_p (arg2, &s2))
1589 return NULL_TREE;
1590 if (s2 == 0
1591 && !TREE_SIDE_EFFECTS (arg0)
1592 && !TREE_SIDE_EFFECTS (arg1))
1593 return build_int_cst (type, 0);
1594 if ((p0 = c_getstr (arg0, &s0))
1595 && (p1 = c_getstr (arg1, &s1))
1596 && s2 <= s0
1597 && s2 <= s1)
1598 return build_cmp_result (type, memcmp (p0, p1, s2));
1599 return NULL_TREE;
1600
1601 case CFN_BUILT_IN_MEMCHR:
1602 if (!host_size_t_cst_p (arg2, &s2))
1603 return NULL_TREE;
1604 if (s2 == 0
1605 && !TREE_SIDE_EFFECTS (arg0)
1606 && !TREE_SIDE_EFFECTS (arg1))
1607 return build_int_cst (type, 0);
1608 if ((p0 = c_getstr (arg0, &s0))
1609 && s2 <= s0
1610 && target_char_cst_p (arg1, &c))
1611 {
1612 const char *r = (const char *) memchr (p0, c, s2);
1613 if (r == NULL)
1614 return build_int_cst (type, 0);
1615 return fold_convert (type,
1616 fold_build_pointer_plus_hwi (arg0, r - p0));
1617 }
1618 return NULL_TREE;
1619
1620 default:
1621 return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1622 }
1623}
1624
1625/* Fold a fma operation with arguments ARG[012]. */
1626
1627tree
1628fold_fma (location_t, tree type, tree arg0, tree arg1, tree arg2)
1629{
1630 REAL_VALUE_TYPE result;
1631 if (real_cst_p (arg0)
1632 && real_cst_p (arg1)
1633 && real_cst_p (arg2)
1634 && do_mpfr_arg3 (&result, mpfr_fma, TREE_REAL_CST_PTR (arg0),
1635 TREE_REAL_CST_PTR (arg1), TREE_REAL_CST_PTR (arg2),
1636 REAL_MODE_FORMAT (TYPE_MODE (type))))
1637 return build_real (type, result);
1638
1639 return NULL_TREE;
1640}
1641