* c-gimplify.c (c_gimplify_expr): Handle [LR]ROTATE_EXPR like
[official-gcc.git] / gcc / fold-const-call.c
blob98ac09117434dc7f49726ac6c6707edaa35a5407
1 /* Constant folding for calls to built-in and internal functions.
2 Copyright (C) 1988-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
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"
34 /* Functions that test for certain constant types, abstracting away the
35 decision about whether to check for overflow. */
37 static inline bool
38 integer_cst_p (tree t)
40 return TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t);
43 static inline bool
44 real_cst_p (tree t)
46 return TREE_CODE (t) == REAL_CST && !TREE_OVERFLOW (t);
49 static inline bool
50 complex_cst_p (tree t)
52 return TREE_CODE (t) == COMPLEX_CST;
55 /* Return true if ARG is a constant in the range of the host size_t.
56 Store it in *SIZE_OUT if so. */
58 static inline bool
59 host_size_t_cst_p (tree t, size_t *size_out)
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))
66 *size_out = tree_to_uhwi (t);
67 return true;
69 return false;
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. */
76 tree
77 build_cmp_result (tree type, int res)
79 return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0);
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. */
87 static bool
88 do_mpfr_ckconv (real_value *result, mpfr_srcptr m, bool inexact,
89 const real_format *format)
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;
100 REAL_VALUE_TYPE tmp;
101 real_from_mpfr (&tmp, m, format, GMP_RNDN);
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;
110 real_convert (result, format, &tmp);
111 return real_identical (result, &tmp);
114 /* Try to evaluate:
116 *RESULT = f (*ARG)
118 in format FORMAT, given that FUNC is the MPFR implementation of f.
119 Return true on success. */
121 static bool
122 do_mpfr_arg1 (real_value *result,
123 int (*func) (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
124 const real_value *arg, const real_format *format)
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;
131 int prec = format->p;
132 mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
133 mpfr_t m;
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);
142 return ok;
145 /* Try to evaluate:
147 *RESULT_SIN = sin (*ARG);
148 *RESULT_COS = cos (*ARG);
150 for format FORMAT. Return true on success. */
152 static bool
153 do_mpfr_sincos (real_value *result_sin, real_value *result_cos,
154 const real_value *arg, const real_format *format)
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;
161 int prec = format->p;
162 mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
163 mpfr_t m, ms, mc;
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);
173 return ok;
176 /* Try to evaluate:
178 *RESULT = f (*ARG0, *ARG1)
180 in format FORMAT, given that FUNC is the MPFR implementation of f.
181 Return true on success. */
183 static bool
184 do_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)
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;
194 int prec = format->p;
195 mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
196 mpfr_t m0, m1;
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);
206 return ok;
209 /* Try to evaluate:
211 *RESULT = f (ARG0, *ARG1)
213 in format FORMAT, given that FUNC is the MPFR implementation of f.
214 Return true on success. */
216 static bool
217 do_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)
222 if (format->b != 2 || !real_isfinite (arg1))
223 return false;
225 int prec = format->p;
226 mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
227 mpfr_t m;
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);
236 return ok;
239 /* Try to evaluate:
241 *RESULT = f (*ARG0, *ARG1, *ARG2)
243 in format FORMAT, given that FUNC is the MPFR implementation of f.
244 Return true on success. */
246 static bool
247 do_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)
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;
261 int prec = format->p;
262 mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
263 mpfr_t m0, m1, m2;
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);
274 return ok;
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. */
283 static bool
284 do_mpc_ckconv (real_value *result_real, real_value *result_imag,
285 mpc_srcptr m, bool inexact, const real_format *format)
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;
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);
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;
310 real_convert (result_real, format, &tmp_real);
311 real_convert (result_imag, format, &tmp_imag);
313 return (real_identical (result_real, &tmp_real)
314 && real_identical (result_imag, &tmp_imag));
317 /* Try to evaluate:
319 RESULT = f (ARG)
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. */
325 static bool
326 do_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)
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;
338 int prec = format->p;
339 mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
340 mpc_t m;
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);
350 return ok;
353 /* Try to evaluate:
355 RESULT = f (ARG0, ARG1)
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. */
361 static bool
362 do_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)
368 if (!real_isfinite (arg0_real)
369 || !real_isfinite (arg0_imag)
370 || !real_isfinite (arg1_real)
371 || !real_isfinite (arg1_imag))
372 return false;
374 int prec = format->p;
375 mpc_rnd_t crnd = format->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
376 mpc_t m0, m1;
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);
390 return ok;
393 /* Try to evaluate:
395 *RESULT = logb (*ARG)
397 in format FORMAT. Return true on success. */
399 static bool
400 fold_const_logb (real_value *result, const real_value *arg,
401 const real_format *format)
403 switch (arg->cl)
405 case rvc_nan:
406 /* If arg is +-NaN, then return it. */
407 *result = *arg;
408 return true;
410 case rvc_inf:
411 /* If arg is +-Inf, then return +Inf. */
412 *result = *arg;
413 result->sign = 0;
414 return true;
416 case rvc_zero:
417 /* Zero may set errno and/or raise an exception. */
418 return false;
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)
427 real_from_integer (result, format, REAL_EXP (arg) - 1, SIGNED);
428 return true;
430 return false;
432 gcc_unreachable ();
435 /* Try to evaluate:
437 *RESULT = significand (*ARG)
439 in format FORMAT. Return true on success. */
441 static bool
442 fold_const_significand (real_value *result, const real_value *arg,
443 const real_format *format)
445 switch (arg->cl)
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;
454 case rvc_normal:
455 /* For normal numbers, proceed iff radix == 2. */
456 if (format->b == 2)
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;
464 return false;
466 gcc_unreachable ();
469 /* Try to evaluate:
471 *RESULT = f (*ARG)
473 where FORMAT is the format of *ARG and PRECISION is the number of
474 significant bits in the result. Return true on success. */
476 static bool
477 fold_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)
483 if (!real_isfinite (arg))
484 return false;
486 real_value rounded;
487 fn (&rounded, format, arg);
489 bool fail = false;
490 *result = real_to_integer (&rounded, &fail, precision);
491 return !fail;
494 /* Try to evaluate:
496 *RESULT = pow (*ARG0, *ARG1)
498 in format FORMAT. Return true on success. */
500 static bool
501 fold_const_pow (real_value *result, const real_value *arg0,
502 const real_value *arg1, const real_format *format)
504 if (do_mpfr_arg2 (result, mpfr_pow, arg0, arg1, format))
505 return true;
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)))
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;
527 return false;
530 /* Try to evaluate:
532 *RESULT = ldexp (*ARG0, ARG1)
534 in format FORMAT. Return true on success. */
536 static bool
537 fold_const_builtin_load_exponent (real_value *result, const real_value *arg0,
538 const wide_int_ref &arg1,
539 const real_format *format)
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);
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;
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;
559 REAL_VALUE_TYPE initial_result;
560 real_ldexp (&initial_result, arg0, arg1.to_shwi ());
562 /* Ensure we didn't overflow. */
563 if (real_isinf (&initial_result))
564 return false;
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);
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. */
576 static tree
577 fold_const_builtin_nan (tree type, tree arg, bool quiet)
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;
586 /* Try to evaluate:
588 *RESULT = FN (*ARG)
590 in format FORMAT. Return true on success. */
592 static bool
593 fold_const_call_ss (real_value *result, combined_fn fn,
594 const real_value *arg, const real_format *format)
596 switch (fn)
598 CASE_CFN_SQRT:
599 return (real_compare (GE_EXPR, arg, &dconst0)
600 && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
602 CASE_CFN_CBRT:
603 return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
605 CASE_CFN_ASIN:
606 return (real_compare (GE_EXPR, arg, &dconstm1)
607 && real_compare (LE_EXPR, arg, &dconst1)
608 && do_mpfr_arg1 (result, mpfr_asin, arg, format));
610 CASE_CFN_ACOS:
611 return (real_compare (GE_EXPR, arg, &dconstm1)
612 && real_compare (LE_EXPR, arg, &dconst1)
613 && do_mpfr_arg1 (result, mpfr_acos, arg, format));
615 CASE_CFN_ATAN:
616 return do_mpfr_arg1 (result, mpfr_atan, arg, format);
618 CASE_CFN_ASINH:
619 return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
621 CASE_CFN_ACOSH:
622 return (real_compare (GE_EXPR, arg, &dconst1)
623 && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
625 CASE_CFN_ATANH:
626 return (real_compare (GE_EXPR, arg, &dconstm1)
627 && real_compare (LE_EXPR, arg, &dconst1)
628 && do_mpfr_arg1 (result, mpfr_atanh, arg, format));
630 CASE_CFN_SIN:
631 return do_mpfr_arg1 (result, mpfr_sin, arg, format);
633 CASE_CFN_COS:
634 return do_mpfr_arg1 (result, mpfr_cos, arg, format);
636 CASE_CFN_TAN:
637 return do_mpfr_arg1 (result, mpfr_tan, arg, format);
639 CASE_CFN_SINH:
640 return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
642 CASE_CFN_COSH:
643 return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
645 CASE_CFN_TANH:
646 return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
648 CASE_CFN_ERF:
649 return do_mpfr_arg1 (result, mpfr_erf, arg, format);
651 CASE_CFN_ERFC:
652 return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
654 CASE_CFN_TGAMMA:
655 return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
657 CASE_CFN_EXP:
658 return do_mpfr_arg1 (result, mpfr_exp, arg, format);
660 CASE_CFN_EXP2:
661 return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
663 CASE_CFN_EXP10:
664 CASE_CFN_POW10:
665 return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
667 CASE_CFN_EXPM1:
668 return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
670 CASE_CFN_LOG:
671 return (real_compare (GT_EXPR, arg, &dconst0)
672 && do_mpfr_arg1 (result, mpfr_log, arg, format));
674 CASE_CFN_LOG2:
675 return (real_compare (GT_EXPR, arg, &dconst0)
676 && do_mpfr_arg1 (result, mpfr_log2, arg, format));
678 CASE_CFN_LOG10:
679 return (real_compare (GT_EXPR, arg, &dconst0)
680 && do_mpfr_arg1 (result, mpfr_log10, arg, format));
682 CASE_CFN_LOG1P:
683 return (real_compare (GT_EXPR, arg, &dconstm1)
684 && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
686 CASE_CFN_J0:
687 return do_mpfr_arg1 (result, mpfr_j0, arg, format);
689 CASE_CFN_J1:
690 return do_mpfr_arg1 (result, mpfr_j1, arg, format);
692 CASE_CFN_Y0:
693 return (real_compare (GT_EXPR, arg, &dconst0)
694 && do_mpfr_arg1 (result, mpfr_y0, arg, format));
696 CASE_CFN_Y1:
697 return (real_compare (GT_EXPR, arg, &dconst0)
698 && do_mpfr_arg1 (result, mpfr_y1, arg, format));
700 CASE_CFN_FLOOR:
701 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
703 real_floor (result, format, arg);
704 return true;
706 return false;
708 CASE_CFN_CEIL:
709 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
711 real_ceil (result, format, arg);
712 return true;
714 return false;
716 CASE_CFN_TRUNC:
717 real_trunc (result, format, arg);
718 return true;
720 CASE_CFN_ROUND:
721 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
723 real_round (result, format, arg);
724 return true;
726 return false;
728 CASE_CFN_LOGB:
729 return fold_const_logb (result, arg, format);
731 CASE_CFN_SIGNIFICAND:
732 return fold_const_significand (result, arg, format);
734 default:
735 return false;
739 /* Try to evaluate:
741 *RESULT = FN (*ARG)
743 where FORMAT is the format of ARG and PRECISION is the number of
744 significant bits in the result. Return true on success. */
746 static bool
747 fold_const_call_ss (wide_int *result, combined_fn fn,
748 const real_value *arg, unsigned int precision,
749 const real_format *format)
751 switch (fn)
753 CASE_CFN_SIGNBIT:
754 if (real_isneg (arg))
755 *result = wi::one (precision);
756 else
757 *result = wi::zero (precision);
758 return true;
760 CASE_CFN_ILOGB:
761 /* For ilogb we don't know FP_ILOGB0, so only handle normal values.
762 Proceed iff radix == 2. In GCC, normalized significands are in
763 the range [0.5, 1.0). We want the exponent as if they were
764 [1.0, 2.0) so get the exponent and subtract 1. */
765 if (arg->cl == rvc_normal && format->b == 2)
767 *result = wi::shwi (REAL_EXP (arg) - 1, precision);
768 return true;
770 return false;
772 CASE_CFN_ICEIL:
773 CASE_CFN_LCEIL:
774 CASE_CFN_LLCEIL:
775 return fold_const_conversion (result, real_ceil, arg,
776 precision, format);
778 CASE_CFN_LFLOOR:
779 CASE_CFN_IFLOOR:
780 CASE_CFN_LLFLOOR:
781 return fold_const_conversion (result, real_floor, arg,
782 precision, format);
784 CASE_CFN_IROUND:
785 CASE_CFN_LROUND:
786 CASE_CFN_LLROUND:
787 return fold_const_conversion (result, real_round, arg,
788 precision, format);
790 CASE_CFN_IRINT:
791 CASE_CFN_LRINT:
792 CASE_CFN_LLRINT:
793 /* Not yet folded to a constant. */
794 return false;
796 CASE_CFN_FINITE:
797 case CFN_BUILT_IN_FINITED32:
798 case CFN_BUILT_IN_FINITED64:
799 case CFN_BUILT_IN_FINITED128:
800 case CFN_BUILT_IN_ISFINITE:
801 *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
802 return true;
804 CASE_CFN_ISINF:
805 case CFN_BUILT_IN_ISINFD32:
806 case CFN_BUILT_IN_ISINFD64:
807 case CFN_BUILT_IN_ISINFD128:
808 if (real_isinf (arg))
809 *result = wi::shwi (arg->sign ? -1 : 1, precision);
810 else
811 *result = wi::shwi (0, precision);
812 return true;
814 CASE_CFN_ISNAN:
815 case CFN_BUILT_IN_ISNAND32:
816 case CFN_BUILT_IN_ISNAND64:
817 case CFN_BUILT_IN_ISNAND128:
818 *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
819 return true;
821 default:
822 return false;
826 /* Try to evaluate:
828 *RESULT = FN (ARG)
830 where ARG_TYPE is the type of ARG and PRECISION is the number of bits
831 in the result. Return true on success. */
833 static bool
834 fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
835 unsigned int precision, tree arg_type)
837 switch (fn)
839 CASE_CFN_FFS:
840 *result = wi::shwi (wi::ffs (arg), precision);
841 return true;
843 CASE_CFN_CLZ:
845 int tmp;
846 if (wi::ne_p (arg, 0))
847 tmp = wi::clz (arg);
848 else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
849 tmp))
850 tmp = TYPE_PRECISION (arg_type);
851 *result = wi::shwi (tmp, precision);
852 return true;
855 CASE_CFN_CTZ:
857 int tmp;
858 if (wi::ne_p (arg, 0))
859 tmp = wi::ctz (arg);
860 else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
861 tmp))
862 tmp = TYPE_PRECISION (arg_type);
863 *result = wi::shwi (tmp, precision);
864 return true;
867 CASE_CFN_CLRSB:
868 *result = wi::shwi (wi::clrsb (arg), precision);
869 return true;
871 CASE_CFN_POPCOUNT:
872 *result = wi::shwi (wi::popcount (arg), precision);
873 return true;
875 CASE_CFN_PARITY:
876 *result = wi::shwi (wi::parity (arg), precision);
877 return true;
879 case CFN_BUILT_IN_BSWAP16:
880 case CFN_BUILT_IN_BSWAP32:
881 case CFN_BUILT_IN_BSWAP64:
882 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
883 return true;
885 default:
886 return false;
890 /* Try to evaluate:
892 RESULT = FN (*ARG)
894 where FORMAT is the format of ARG and of the real and imaginary parts
895 of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively. Return
896 true on success. */
898 static bool
899 fold_const_call_cs (real_value *result_real, real_value *result_imag,
900 combined_fn fn, const real_value *arg,
901 const real_format *format)
903 switch (fn)
905 CASE_CFN_CEXPI:
906 /* cexpi(x+yi) = cos(x)+sin(y)*i. */
907 return do_mpfr_sincos (result_imag, result_real, arg, format);
909 default:
910 return false;
914 /* Try to evaluate:
916 *RESULT = fn (ARG)
918 where FORMAT is the format of RESULT and of the real and imaginary parts
919 of ARG, passed as ARG_REAL and ARG_IMAG respectively. Return true on
920 success. */
922 static bool
923 fold_const_call_sc (real_value *result, combined_fn fn,
924 const real_value *arg_real, const real_value *arg_imag,
925 const real_format *format)
927 switch (fn)
929 CASE_CFN_CABS:
930 return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
932 default:
933 return false;
937 /* Try to evaluate:
939 RESULT = fn (ARG)
941 where FORMAT is the format of the real and imaginary parts of RESULT
942 (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
943 Return true on success. */
945 static bool
946 fold_const_call_cc (real_value *result_real, real_value *result_imag,
947 combined_fn fn, const real_value *arg_real,
948 const real_value *arg_imag, const real_format *format)
950 switch (fn)
952 CASE_CFN_CCOS:
953 return do_mpc_arg1 (result_real, result_imag, mpc_cos,
954 arg_real, arg_imag, format);
956 CASE_CFN_CCOSH:
957 return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
958 arg_real, arg_imag, format);
960 CASE_CFN_CPROJ:
961 if (real_isinf (arg_real) || real_isinf (arg_imag))
963 real_inf (result_real);
964 *result_imag = dconst0;
965 result_imag->sign = arg_imag->sign;
967 else
969 *result_real = *arg_real;
970 *result_imag = *arg_imag;
972 return true;
974 CASE_CFN_CSIN:
975 return do_mpc_arg1 (result_real, result_imag, mpc_sin,
976 arg_real, arg_imag, format);
978 CASE_CFN_CSINH:
979 return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
980 arg_real, arg_imag, format);
982 CASE_CFN_CTAN:
983 return do_mpc_arg1 (result_real, result_imag, mpc_tan,
984 arg_real, arg_imag, format);
986 CASE_CFN_CTANH:
987 return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
988 arg_real, arg_imag, format);
990 CASE_CFN_CLOG:
991 return do_mpc_arg1 (result_real, result_imag, mpc_log,
992 arg_real, arg_imag, format);
994 CASE_CFN_CSQRT:
995 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
996 arg_real, arg_imag, format);
998 CASE_CFN_CASIN:
999 return do_mpc_arg1 (result_real, result_imag, mpc_asin,
1000 arg_real, arg_imag, format);
1002 CASE_CFN_CACOS:
1003 return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1004 arg_real, arg_imag, format);
1006 CASE_CFN_CATAN:
1007 return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1008 arg_real, arg_imag, format);
1010 CASE_CFN_CASINH:
1011 return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1012 arg_real, arg_imag, format);
1014 CASE_CFN_CACOSH:
1015 return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1016 arg_real, arg_imag, format);
1018 CASE_CFN_CATANH:
1019 return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1020 arg_real, arg_imag, format);
1022 CASE_CFN_CEXP:
1023 return do_mpc_arg1 (result_real, result_imag, mpc_exp,
1024 arg_real, arg_imag, format);
1026 default:
1027 return false;
1031 /* Subroutine of fold_const_call, with the same interface. Handle cases
1032 where the arguments and result are numerical. */
1034 static tree
1035 fold_const_call_1 (combined_fn fn, tree type, tree arg)
1037 machine_mode mode = TYPE_MODE (type);
1038 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1040 if (integer_cst_p (arg))
1042 if (SCALAR_INT_MODE_P (mode))
1044 wide_int result;
1045 if (fold_const_call_ss (&result, fn, wi::to_wide (arg),
1046 TYPE_PRECISION (type), TREE_TYPE (arg)))
1047 return wide_int_to_tree (type, result);
1049 return NULL_TREE;
1052 if (real_cst_p (arg))
1054 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
1055 if (mode == arg_mode)
1057 /* real -> real. */
1058 REAL_VALUE_TYPE result;
1059 if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
1060 REAL_MODE_FORMAT (mode)))
1061 return build_real (type, result);
1063 else if (COMPLEX_MODE_P (mode)
1064 && GET_MODE_INNER (mode) == arg_mode)
1066 /* real -> complex real. */
1067 REAL_VALUE_TYPE result_real, result_imag;
1068 if (fold_const_call_cs (&result_real, &result_imag, fn,
1069 TREE_REAL_CST_PTR (arg),
1070 REAL_MODE_FORMAT (arg_mode)))
1071 return build_complex (type,
1072 build_real (TREE_TYPE (type), result_real),
1073 build_real (TREE_TYPE (type), result_imag));
1075 else if (INTEGRAL_TYPE_P (type))
1077 /* real -> int. */
1078 wide_int result;
1079 if (fold_const_call_ss (&result, fn,
1080 TREE_REAL_CST_PTR (arg),
1081 TYPE_PRECISION (type),
1082 REAL_MODE_FORMAT (arg_mode)))
1083 return wide_int_to_tree (type, result);
1085 return NULL_TREE;
1088 if (complex_cst_p (arg))
1090 gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
1091 machine_mode inner_mode = GET_MODE_INNER (arg_mode);
1092 tree argr = TREE_REALPART (arg);
1093 tree argi = TREE_IMAGPART (arg);
1094 if (mode == arg_mode
1095 && real_cst_p (argr)
1096 && real_cst_p (argi))
1098 /* complex real -> complex real. */
1099 REAL_VALUE_TYPE result_real, result_imag;
1100 if (fold_const_call_cc (&result_real, &result_imag, fn,
1101 TREE_REAL_CST_PTR (argr),
1102 TREE_REAL_CST_PTR (argi),
1103 REAL_MODE_FORMAT (inner_mode)))
1104 return build_complex (type,
1105 build_real (TREE_TYPE (type), result_real),
1106 build_real (TREE_TYPE (type), result_imag));
1108 if (mode == inner_mode
1109 && real_cst_p (argr)
1110 && real_cst_p (argi))
1112 /* complex real -> real. */
1113 REAL_VALUE_TYPE result;
1114 if (fold_const_call_sc (&result, fn,
1115 TREE_REAL_CST_PTR (argr),
1116 TREE_REAL_CST_PTR (argi),
1117 REAL_MODE_FORMAT (inner_mode)))
1118 return build_real (type, result);
1120 return NULL_TREE;
1123 return NULL_TREE;
1126 /* Try to fold FN (ARG) to a constant. Return the constant on success,
1127 otherwise return null. TYPE is the type of the return value. */
1129 tree
1130 fold_const_call (combined_fn fn, tree type, tree arg)
1132 switch (fn)
1134 case CFN_BUILT_IN_STRLEN:
1135 if (const char *str = c_getstr (arg))
1136 return build_int_cst (type, strlen (str));
1137 return NULL_TREE;
1139 CASE_CFN_NAN:
1140 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
1141 case CFN_BUILT_IN_NAND32:
1142 case CFN_BUILT_IN_NAND64:
1143 case CFN_BUILT_IN_NAND128:
1144 return fold_const_builtin_nan (type, arg, true);
1146 CASE_CFN_NANS:
1147 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
1148 return fold_const_builtin_nan (type, arg, false);
1150 default:
1151 return fold_const_call_1 (fn, type, arg);
1155 /* Try to evaluate:
1157 *RESULT = FN (*ARG0, *ARG1)
1159 in format FORMAT. Return true on success. */
1161 static bool
1162 fold_const_call_sss (real_value *result, combined_fn fn,
1163 const real_value *arg0, const real_value *arg1,
1164 const real_format *format)
1166 switch (fn)
1168 CASE_CFN_DREM:
1169 CASE_CFN_REMAINDER:
1170 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1172 CASE_CFN_ATAN2:
1173 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1175 CASE_CFN_FDIM:
1176 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1178 CASE_CFN_HYPOT:
1179 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1181 CASE_CFN_COPYSIGN:
1182 *result = *arg0;
1183 real_copysign (result, arg1);
1184 return true;
1186 CASE_CFN_FMIN:
1187 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1189 CASE_CFN_FMAX:
1190 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1192 CASE_CFN_POW:
1193 return fold_const_pow (result, arg0, arg1, format);
1195 default:
1196 return false;
1200 /* Try to evaluate:
1202 *RESULT = FN (*ARG0, ARG1)
1204 where FORMAT is the format of *RESULT and *ARG0. Return true on
1205 success. */
1207 static bool
1208 fold_const_call_sss (real_value *result, combined_fn fn,
1209 const real_value *arg0, const wide_int_ref &arg1,
1210 const real_format *format)
1212 switch (fn)
1214 CASE_CFN_LDEXP:
1215 return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1217 CASE_CFN_SCALBN:
1218 CASE_CFN_SCALBLN:
1219 return (format->b == 2
1220 && fold_const_builtin_load_exponent (result, arg0, arg1,
1221 format));
1223 CASE_CFN_POWI:
1224 /* Avoid the folding if flag_signaling_nans is on and
1225 operand is a signaling NaN. */
1226 if (!flag_unsafe_math_optimizations
1227 && flag_signaling_nans
1228 && REAL_VALUE_ISSIGNALING_NAN (*arg0))
1229 return false;
1231 real_powi (result, format, arg0, arg1.to_shwi ());
1232 return true;
1234 default:
1235 return false;
1239 /* Try to evaluate:
1241 *RESULT = FN (ARG0, *ARG1)
1243 where FORMAT is the format of *RESULT and *ARG1. Return true on
1244 success. */
1246 static bool
1247 fold_const_call_sss (real_value *result, combined_fn fn,
1248 const wide_int_ref &arg0, const real_value *arg1,
1249 const real_format *format)
1251 switch (fn)
1253 CASE_CFN_JN:
1254 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1256 CASE_CFN_YN:
1257 return (real_compare (GT_EXPR, arg1, &dconst0)
1258 && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
1260 default:
1261 return false;
1265 /* Try to evaluate:
1267 RESULT = fn (ARG0, ARG1)
1269 where FORMAT is the format of the real and imaginary parts of RESULT
1270 (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
1271 and of ARG1 (ARG1_REAL and ARG1_IMAG). Return true on success. */
1273 static bool
1274 fold_const_call_ccc (real_value *result_real, real_value *result_imag,
1275 combined_fn fn, const real_value *arg0_real,
1276 const real_value *arg0_imag, const real_value *arg1_real,
1277 const real_value *arg1_imag, const real_format *format)
1279 switch (fn)
1281 CASE_CFN_CPOW:
1282 return do_mpc_arg2 (result_real, result_imag, mpc_pow,
1283 arg0_real, arg0_imag, arg1_real, arg1_imag, format);
1285 default:
1286 return false;
1290 /* Subroutine of fold_const_call, with the same interface. Handle cases
1291 where the arguments and result are numerical. */
1293 static tree
1294 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
1296 machine_mode mode = TYPE_MODE (type);
1297 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1298 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1300 if (arg0_mode == arg1_mode
1301 && real_cst_p (arg0)
1302 && real_cst_p (arg1))
1304 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1305 if (mode == arg0_mode)
1307 /* real, real -> real. */
1308 REAL_VALUE_TYPE result;
1309 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1310 TREE_REAL_CST_PTR (arg1),
1311 REAL_MODE_FORMAT (mode)))
1312 return build_real (type, result);
1314 return NULL_TREE;
1317 if (real_cst_p (arg0)
1318 && integer_cst_p (arg1))
1320 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1321 if (mode == arg0_mode)
1323 /* real, int -> real. */
1324 REAL_VALUE_TYPE result;
1325 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1326 wi::to_wide (arg1),
1327 REAL_MODE_FORMAT (mode)))
1328 return build_real (type, result);
1330 return NULL_TREE;
1333 if (integer_cst_p (arg0)
1334 && real_cst_p (arg1))
1336 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
1337 if (mode == arg1_mode)
1339 /* int, real -> real. */
1340 REAL_VALUE_TYPE result;
1341 if (fold_const_call_sss (&result, fn, wi::to_wide (arg0),
1342 TREE_REAL_CST_PTR (arg1),
1343 REAL_MODE_FORMAT (mode)))
1344 return build_real (type, result);
1346 return NULL_TREE;
1349 if (arg0_mode == arg1_mode
1350 && complex_cst_p (arg0)
1351 && complex_cst_p (arg1))
1353 gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
1354 machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
1355 tree arg0r = TREE_REALPART (arg0);
1356 tree arg0i = TREE_IMAGPART (arg0);
1357 tree arg1r = TREE_REALPART (arg1);
1358 tree arg1i = TREE_IMAGPART (arg1);
1359 if (mode == arg0_mode
1360 && real_cst_p (arg0r)
1361 && real_cst_p (arg0i)
1362 && real_cst_p (arg1r)
1363 && real_cst_p (arg1i))
1365 /* complex real, complex real -> complex real. */
1366 REAL_VALUE_TYPE result_real, result_imag;
1367 if (fold_const_call_ccc (&result_real, &result_imag, fn,
1368 TREE_REAL_CST_PTR (arg0r),
1369 TREE_REAL_CST_PTR (arg0i),
1370 TREE_REAL_CST_PTR (arg1r),
1371 TREE_REAL_CST_PTR (arg1i),
1372 REAL_MODE_FORMAT (inner_mode)))
1373 return build_complex (type,
1374 build_real (TREE_TYPE (type), result_real),
1375 build_real (TREE_TYPE (type), result_imag));
1377 return NULL_TREE;
1380 return NULL_TREE;
1383 /* Try to fold FN (ARG0, ARG1) to a constant. Return the constant on success,
1384 otherwise return null. TYPE is the type of the return value. */
1386 tree
1387 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
1389 const char *p0, *p1;
1390 char c;
1391 switch (fn)
1393 case CFN_BUILT_IN_STRSPN:
1394 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1395 return build_int_cst (type, strspn (p0, p1));
1396 return NULL_TREE;
1398 case CFN_BUILT_IN_STRCSPN:
1399 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1400 return build_int_cst (type, strcspn (p0, p1));
1401 return NULL_TREE;
1403 case CFN_BUILT_IN_STRCMP:
1404 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1405 return build_cmp_result (type, strcmp (p0, p1));
1406 return NULL_TREE;
1408 case CFN_BUILT_IN_STRCASECMP:
1409 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1411 int r = strcmp (p0, p1);
1412 if (r == 0)
1413 return build_cmp_result (type, r);
1415 return NULL_TREE;
1417 case CFN_BUILT_IN_INDEX:
1418 case CFN_BUILT_IN_STRCHR:
1419 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1421 const char *r = strchr (p0, c);
1422 if (r == NULL)
1423 return build_int_cst (type, 0);
1424 return fold_convert (type,
1425 fold_build_pointer_plus_hwi (arg0, r - p0));
1427 return NULL_TREE;
1429 case CFN_BUILT_IN_RINDEX:
1430 case CFN_BUILT_IN_STRRCHR:
1431 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1433 const char *r = strrchr (p0, c);
1434 if (r == NULL)
1435 return build_int_cst (type, 0);
1436 return fold_convert (type,
1437 fold_build_pointer_plus_hwi (arg0, r - p0));
1439 return NULL_TREE;
1441 case CFN_BUILT_IN_STRSTR:
1442 if ((p1 = c_getstr (arg1)))
1444 if ((p0 = c_getstr (arg0)))
1446 const char *r = strstr (p0, p1);
1447 if (r == NULL)
1448 return build_int_cst (type, 0);
1449 return fold_convert (type,
1450 fold_build_pointer_plus_hwi (arg0, r - p0));
1452 if (*p1 == '\0')
1453 return fold_convert (type, arg0);
1455 return NULL_TREE;
1457 default:
1458 return fold_const_call_1 (fn, type, arg0, arg1);
1462 /* Try to evaluate:
1464 *RESULT = FN (*ARG0, *ARG1, *ARG2)
1466 in format FORMAT. Return true on success. */
1468 static bool
1469 fold_const_call_ssss (real_value *result, combined_fn fn,
1470 const real_value *arg0, const real_value *arg1,
1471 const real_value *arg2, const real_format *format)
1473 switch (fn)
1475 CASE_CFN_FMA:
1476 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1478 default:
1479 return false;
1483 /* Subroutine of fold_const_call, with the same interface. Handle cases
1484 where the arguments and result are numerical. */
1486 static tree
1487 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1489 machine_mode mode = TYPE_MODE (type);
1490 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1491 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1492 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
1494 if (arg0_mode == arg1_mode
1495 && arg0_mode == arg2_mode
1496 && real_cst_p (arg0)
1497 && real_cst_p (arg1)
1498 && real_cst_p (arg2))
1500 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1501 if (mode == arg0_mode)
1503 /* real, real, real -> real. */
1504 REAL_VALUE_TYPE result;
1505 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
1506 TREE_REAL_CST_PTR (arg1),
1507 TREE_REAL_CST_PTR (arg2),
1508 REAL_MODE_FORMAT (mode)))
1509 return build_real (type, result);
1511 return NULL_TREE;
1514 return NULL_TREE;
1517 /* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on
1518 success, otherwise return null. TYPE is the type of the return value. */
1520 tree
1521 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1523 const char *p0, *p1;
1524 char c;
1525 unsigned HOST_WIDE_INT s0, s1;
1526 size_t s2 = 0;
1527 switch (fn)
1529 case CFN_BUILT_IN_STRNCMP:
1530 if (!host_size_t_cst_p (arg2, &s2))
1531 return NULL_TREE;
1532 if (s2 == 0
1533 && !TREE_SIDE_EFFECTS (arg0)
1534 && !TREE_SIDE_EFFECTS (arg1))
1535 return build_int_cst (type, 0);
1536 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1537 return build_int_cst (type, strncmp (p0, p1, s2));
1538 return NULL_TREE;
1540 case CFN_BUILT_IN_STRNCASECMP:
1541 if (!host_size_t_cst_p (arg2, &s2))
1542 return NULL_TREE;
1543 if (s2 == 0
1544 && !TREE_SIDE_EFFECTS (arg0)
1545 && !TREE_SIDE_EFFECTS (arg1))
1546 return build_int_cst (type, 0);
1547 else if ((p0 = c_getstr (arg0))
1548 && (p1 = c_getstr (arg1))
1549 && strncmp (p0, p1, s2) == 0)
1550 return build_int_cst (type, 0);
1551 return NULL_TREE;
1553 case CFN_BUILT_IN_BCMP:
1554 case CFN_BUILT_IN_MEMCMP:
1555 if (!host_size_t_cst_p (arg2, &s2))
1556 return NULL_TREE;
1557 if (s2 == 0
1558 && !TREE_SIDE_EFFECTS (arg0)
1559 && !TREE_SIDE_EFFECTS (arg1))
1560 return build_int_cst (type, 0);
1561 if ((p0 = c_getstr (arg0, &s0))
1562 && (p1 = c_getstr (arg1, &s1))
1563 && s2 <= s0
1564 && s2 <= s1)
1565 return build_cmp_result (type, memcmp (p0, p1, s2));
1566 return NULL_TREE;
1568 case CFN_BUILT_IN_MEMCHR:
1569 if (!host_size_t_cst_p (arg2, &s2))
1570 return NULL_TREE;
1571 if (s2 == 0
1572 && !TREE_SIDE_EFFECTS (arg0)
1573 && !TREE_SIDE_EFFECTS (arg1))
1574 return build_int_cst (type, 0);
1575 if ((p0 = c_getstr (arg0, &s0))
1576 && s2 <= s0
1577 && target_char_cst_p (arg1, &c))
1579 const char *r = (const char *) memchr (p0, c, s2);
1580 if (r == NULL)
1581 return build_int_cst (type, 0);
1582 return fold_convert (type,
1583 fold_build_pointer_plus_hwi (arg0, r - p0));
1585 return NULL_TREE;
1587 default:
1588 return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1592 /* Fold a fma operation with arguments ARG[012]. */
1594 tree
1595 fold_fma (location_t, tree type, tree arg0, tree arg1, tree arg2)
1597 REAL_VALUE_TYPE result;
1598 if (real_cst_p (arg0)
1599 && real_cst_p (arg1)
1600 && real_cst_p (arg2)
1601 && do_mpfr_arg3 (&result, mpfr_fma, TREE_REAL_CST_PTR (arg0),
1602 TREE_REAL_CST_PTR (arg1), TREE_REAL_CST_PTR (arg2),
1603 REAL_MODE_FORMAT (TYPE_MODE (type))))
1604 return build_real (type, result);
1606 return NULL_TREE;