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