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