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