]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/fold-const-call.c
re PR c++/71537 (GCC rejects consetxpr boolean conversions and comparisons on the...
[thirdparty/gcc.git] / gcc / fold-const-call.c
1 /* Constant folding for calls to built-in and internal functions.
2 Copyright (C) 1988-2016 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 (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
75 tree
76 build_cmp_result (tree type, int res)
77 {
78 return build_int_cst (type, res < 0 ? -1 : res > 0 ? 1 : 0);
79 }
80
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
86 static bool
87 do_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
120 static bool
121 do_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
151 static bool
152 do_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
182 static bool
183 do_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
215 static bool
216 do_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
245 static bool
246 do_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
282 static bool
283 do_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
324 static bool
325 do_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
360 static bool
361 do_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
398 static bool
399 fold_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
440 static bool
441 fold_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
475 static bool
476 fold_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
499 static bool
500 fold_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);
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))))
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
535 static bool
536 fold_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
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
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
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
575 static tree
576 fold_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
585 /* Try to evaluate:
586
587 *RESULT = FN (*ARG)
588
589 in format FORMAT. Return true on success. */
590
591 static bool
592 fold_const_call_ss (real_value *result, combined_fn fn,
593 const real_value *arg, const real_format *format)
594 {
595 switch (fn)
596 {
597 CASE_CFN_SQRT:
598 return (real_compare (GE_EXPR, arg, &dconst0)
599 && do_mpfr_arg1 (result, mpfr_sqrt, arg, format));
600
601 CASE_CFN_CBRT:
602 return do_mpfr_arg1 (result, mpfr_cbrt, arg, format);
603
604 CASE_CFN_ASIN:
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
609 CASE_CFN_ACOS:
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
614 CASE_CFN_ATAN:
615 return do_mpfr_arg1 (result, mpfr_atan, arg, format);
616
617 CASE_CFN_ASINH:
618 return do_mpfr_arg1 (result, mpfr_asinh, arg, format);
619
620 CASE_CFN_ACOSH:
621 return (real_compare (GE_EXPR, arg, &dconst1)
622 && do_mpfr_arg1 (result, mpfr_acosh, arg, format));
623
624 CASE_CFN_ATANH:
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
629 CASE_CFN_SIN:
630 return do_mpfr_arg1 (result, mpfr_sin, arg, format);
631
632 CASE_CFN_COS:
633 return do_mpfr_arg1 (result, mpfr_cos, arg, format);
634
635 CASE_CFN_TAN:
636 return do_mpfr_arg1 (result, mpfr_tan, arg, format);
637
638 CASE_CFN_SINH:
639 return do_mpfr_arg1 (result, mpfr_sinh, arg, format);
640
641 CASE_CFN_COSH:
642 return do_mpfr_arg1 (result, mpfr_cosh, arg, format);
643
644 CASE_CFN_TANH:
645 return do_mpfr_arg1 (result, mpfr_tanh, arg, format);
646
647 CASE_CFN_ERF:
648 return do_mpfr_arg1 (result, mpfr_erf, arg, format);
649
650 CASE_CFN_ERFC:
651 return do_mpfr_arg1 (result, mpfr_erfc, arg, format);
652
653 CASE_CFN_TGAMMA:
654 return do_mpfr_arg1 (result, mpfr_gamma, arg, format);
655
656 CASE_CFN_EXP:
657 return do_mpfr_arg1 (result, mpfr_exp, arg, format);
658
659 CASE_CFN_EXP2:
660 return do_mpfr_arg1 (result, mpfr_exp2, arg, format);
661
662 CASE_CFN_EXP10:
663 CASE_CFN_POW10:
664 return do_mpfr_arg1 (result, mpfr_exp10, arg, format);
665
666 CASE_CFN_EXPM1:
667 return do_mpfr_arg1 (result, mpfr_expm1, arg, format);
668
669 CASE_CFN_LOG:
670 return (real_compare (GT_EXPR, arg, &dconst0)
671 && do_mpfr_arg1 (result, mpfr_log, arg, format));
672
673 CASE_CFN_LOG2:
674 return (real_compare (GT_EXPR, arg, &dconst0)
675 && do_mpfr_arg1 (result, mpfr_log2, arg, format));
676
677 CASE_CFN_LOG10:
678 return (real_compare (GT_EXPR, arg, &dconst0)
679 && do_mpfr_arg1 (result, mpfr_log10, arg, format));
680
681 CASE_CFN_LOG1P:
682 return (real_compare (GT_EXPR, arg, &dconstm1)
683 && do_mpfr_arg1 (result, mpfr_log1p, arg, format));
684
685 CASE_CFN_J0:
686 return do_mpfr_arg1 (result, mpfr_j0, arg, format);
687
688 CASE_CFN_J1:
689 return do_mpfr_arg1 (result, mpfr_j1, arg, format);
690
691 CASE_CFN_Y0:
692 return (real_compare (GT_EXPR, arg, &dconst0)
693 && do_mpfr_arg1 (result, mpfr_y0, arg, format));
694
695 CASE_CFN_Y1:
696 return (real_compare (GT_EXPR, arg, &dconst0)
697 && do_mpfr_arg1 (result, mpfr_y1, arg, format));
698
699 CASE_CFN_FLOOR:
700 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
701 {
702 real_floor (result, format, arg);
703 return true;
704 }
705 return false;
706
707 CASE_CFN_CEIL:
708 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
709 {
710 real_ceil (result, format, arg);
711 return true;
712 }
713 return false;
714
715 CASE_CFN_TRUNC:
716 real_trunc (result, format, arg);
717 return true;
718
719 CASE_CFN_ROUND:
720 if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
721 {
722 real_round (result, format, arg);
723 return true;
724 }
725 return false;
726
727 CASE_CFN_LOGB:
728 return fold_const_logb (result, arg, format);
729
730 CASE_CFN_SIGNIFICAND:
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
745 static bool
746 fold_const_call_ss (wide_int *result, combined_fn fn,
747 const real_value *arg, unsigned int precision,
748 const real_format *format)
749 {
750 switch (fn)
751 {
752 CASE_CFN_SIGNBIT:
753 if (real_isneg (arg))
754 *result = wi::one (precision);
755 else
756 *result = wi::zero (precision);
757 return true;
758
759 CASE_CFN_ILOGB:
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
771 CASE_CFN_ICEIL:
772 CASE_CFN_LCEIL:
773 CASE_CFN_LLCEIL:
774 return fold_const_conversion (result, real_ceil, arg,
775 precision, format);
776
777 CASE_CFN_LFLOOR:
778 CASE_CFN_IFLOOR:
779 CASE_CFN_LLFLOOR:
780 return fold_const_conversion (result, real_floor, arg,
781 precision, format);
782
783 CASE_CFN_IROUND:
784 CASE_CFN_LROUND:
785 CASE_CFN_LLROUND:
786 return fold_const_conversion (result, real_round, arg,
787 precision, format);
788
789 CASE_CFN_IRINT:
790 CASE_CFN_LRINT:
791 CASE_CFN_LLRINT:
792 /* Not yet folded to a constant. */
793 return false;
794
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:
800 *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision);
801 return true;
802
803 CASE_CFN_ISINF:
804 case CFN_BUILT_IN_ISINFD32:
805 case CFN_BUILT_IN_ISINFD64:
806 case CFN_BUILT_IN_ISINFD128:
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
813 CASE_CFN_ISNAN:
814 case CFN_BUILT_IN_ISNAND32:
815 case CFN_BUILT_IN_ISNAND64:
816 case CFN_BUILT_IN_ISNAND128:
817 *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision);
818 return true;
819
820 default:
821 return false;
822 }
823 }
824
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
832 static bool
833 fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
834 unsigned int precision, tree arg_type)
835 {
836 switch (fn)
837 {
838 CASE_CFN_FFS:
839 *result = wi::shwi (wi::ffs (arg), precision);
840 return true;
841
842 CASE_CFN_CLZ:
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
853 CASE_CFN_CTZ:
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
864 CASE_CFN_CLRSB:
865 *result = wi::shwi (wi::clrsb (arg), precision);
866 return true;
867
868 CASE_CFN_POPCOUNT:
869 *result = wi::shwi (wi::popcount (arg), precision);
870 return true;
871
872 CASE_CFN_PARITY:
873 *result = wi::shwi (wi::parity (arg), precision);
874 return true;
875
876 case CFN_BUILT_IN_BSWAP16:
877 case CFN_BUILT_IN_BSWAP32:
878 case CFN_BUILT_IN_BSWAP64:
879 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
880 return true;
881
882 default:
883 return false;
884 }
885 }
886
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
895 static bool
896 fold_const_call_cs (real_value *result_real, real_value *result_imag,
897 combined_fn fn, const real_value *arg,
898 const real_format *format)
899 {
900 switch (fn)
901 {
902 CASE_CFN_CEXPI:
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
919 static bool
920 fold_const_call_sc (real_value *result, combined_fn fn,
921 const real_value *arg_real, const real_value *arg_imag,
922 const real_format *format)
923 {
924 switch (fn)
925 {
926 CASE_CFN_CABS:
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
942 static bool
943 fold_const_call_cc (real_value *result_real, real_value *result_imag,
944 combined_fn fn, const real_value *arg_real,
945 const real_value *arg_imag, const real_format *format)
946 {
947 switch (fn)
948 {
949 CASE_CFN_CCOS:
950 return do_mpc_arg1 (result_real, result_imag, mpc_cos,
951 arg_real, arg_imag, format);
952
953 CASE_CFN_CCOSH:
954 return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
955 arg_real, arg_imag, format);
956
957 CASE_CFN_CPROJ:
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
971 CASE_CFN_CSIN:
972 return do_mpc_arg1 (result_real, result_imag, mpc_sin,
973 arg_real, arg_imag, format);
974
975 CASE_CFN_CSINH:
976 return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
977 arg_real, arg_imag, format);
978
979 CASE_CFN_CTAN:
980 return do_mpc_arg1 (result_real, result_imag, mpc_tan,
981 arg_real, arg_imag, format);
982
983 CASE_CFN_CTANH:
984 return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
985 arg_real, arg_imag, format);
986
987 CASE_CFN_CLOG:
988 return do_mpc_arg1 (result_real, result_imag, mpc_log,
989 arg_real, arg_imag, format);
990
991 CASE_CFN_CSQRT:
992 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
993 arg_real, arg_imag, format);
994
995 CASE_CFN_CASIN:
996 return do_mpc_arg1 (result_real, result_imag, mpc_asin,
997 arg_real, arg_imag, format);
998
999 CASE_CFN_CACOS:
1000 return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1001 arg_real, arg_imag, format);
1002
1003 CASE_CFN_CATAN:
1004 return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1005 arg_real, arg_imag, format);
1006
1007 CASE_CFN_CASINH:
1008 return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1009 arg_real, arg_imag, format);
1010
1011 CASE_CFN_CACOSH:
1012 return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1013 arg_real, arg_imag, format);
1014
1015 CASE_CFN_CATANH:
1016 return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1017 arg_real, arg_imag, format);
1018
1019 CASE_CFN_CEXP:
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
1028 /* Subroutine of fold_const_call, with the same interface. Handle cases
1029 where the arguments and result are numerical. */
1030
1031 static tree
1032 fold_const_call_1 (combined_fn fn, tree type, tree arg)
1033 {
1034 machine_mode mode = TYPE_MODE (type);
1035 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1036
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
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
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
1126 tree
1127 fold_const_call (combined_fn fn, tree type, tree arg)
1128 {
1129 switch (fn)
1130 {
1131 case CFN_BUILT_IN_STRLEN:
1132 if (const char *str = c_getstr (arg))
1133 return build_int_cst (type, strlen (str));
1134 return NULL_TREE;
1135
1136 CASE_CFN_NAN:
1137 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
1138 case CFN_BUILT_IN_NAND32:
1139 case CFN_BUILT_IN_NAND64:
1140 case CFN_BUILT_IN_NAND128:
1141 return fold_const_builtin_nan (type, arg, true);
1142
1143 CASE_CFN_NANS:
1144 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
1145 return fold_const_builtin_nan (type, arg, false);
1146
1147 default:
1148 return fold_const_call_1 (fn, type, arg);
1149 }
1150 }
1151
1152 /* Try to evaluate:
1153
1154 *RESULT = FN (*ARG0, *ARG1)
1155
1156 in format FORMAT. Return true on success. */
1157
1158 static bool
1159 fold_const_call_sss (real_value *result, combined_fn fn,
1160 const real_value *arg0, const real_value *arg1,
1161 const real_format *format)
1162 {
1163 switch (fn)
1164 {
1165 CASE_CFN_DREM:
1166 CASE_CFN_REMAINDER:
1167 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1168
1169 CASE_CFN_ATAN2:
1170 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1171
1172 CASE_CFN_FDIM:
1173 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1174
1175 CASE_CFN_HYPOT:
1176 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1177
1178 CASE_CFN_COPYSIGN:
1179 *result = *arg0;
1180 real_copysign (result, arg1);
1181 return true;
1182
1183 CASE_CFN_FMIN:
1184 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1185
1186 CASE_CFN_FMAX:
1187 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1188
1189 CASE_CFN_POW:
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
1204 static bool
1205 fold_const_call_sss (real_value *result, combined_fn fn,
1206 const real_value *arg0, const wide_int_ref &arg1,
1207 const real_format *format)
1208 {
1209 switch (fn)
1210 {
1211 CASE_CFN_LDEXP:
1212 return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1213
1214 CASE_CFN_SCALBN:
1215 CASE_CFN_SCALBLN:
1216 return (format->b == 2
1217 && fold_const_builtin_load_exponent (result, arg0, arg1,
1218 format));
1219
1220 CASE_CFN_POWI:
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
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
1243 static bool
1244 fold_const_call_sss (real_value *result, combined_fn fn,
1245 const wide_int_ref &arg0, const real_value *arg1,
1246 const real_format *format)
1247 {
1248 switch (fn)
1249 {
1250 CASE_CFN_JN:
1251 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1252
1253 CASE_CFN_YN:
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
1270 static bool
1271 fold_const_call_ccc (real_value *result_real, real_value *result_imag,
1272 combined_fn fn, const real_value *arg0_real,
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 {
1278 CASE_CFN_CPOW:
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
1287 /* Subroutine of fold_const_call, with the same interface. Handle cases
1288 where the arguments and result are numerical. */
1289
1290 static tree
1291 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
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
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
1382 tree
1383 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
1384 {
1385 const char *p0, *p1;
1386 char c;
1387 switch (fn)
1388 {
1389 case CFN_BUILT_IN_STRSPN:
1390 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1391 return build_int_cst (type, strspn (p0, p1));
1392 return NULL_TREE;
1393
1394 case CFN_BUILT_IN_STRCSPN:
1395 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1396 return build_int_cst (type, strcspn (p0, p1));
1397 return NULL_TREE;
1398
1399 case CFN_BUILT_IN_STRCMP:
1400 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1401 return build_cmp_result (type, strcmp (p0, p1));
1402 return NULL_TREE;
1403
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
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
1437 default:
1438 return fold_const_call_1 (fn, type, arg0, arg1);
1439 }
1440 }
1441
1442 /* Try to evaluate:
1443
1444 *RESULT = FN (*ARG0, *ARG1, *ARG2)
1445
1446 in format FORMAT. Return true on success. */
1447
1448 static bool
1449 fold_const_call_ssss (real_value *result, combined_fn fn,
1450 const real_value *arg0, const real_value *arg1,
1451 const real_value *arg2, const real_format *format)
1452 {
1453 switch (fn)
1454 {
1455 CASE_CFN_FMA:
1456 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1457
1458 default:
1459 return false;
1460 }
1461 }
1462
1463 /* Subroutine of fold_const_call, with the same interface. Handle cases
1464 where the arguments and result are numerical. */
1465
1466 static tree
1467 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
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
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
1500 tree
1501 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1502 {
1503 const char *p0, *p1;
1504 char c;
1505 unsigned HOST_WIDE_INT s0, s1;
1506 size_t s2 = 0;
1507 switch (fn)
1508 {
1509 case CFN_BUILT_IN_STRNCMP:
1510 if (!host_size_t_cst_p (arg2, &s2))
1511 return NULL_TREE;
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
1520 case CFN_BUILT_IN_STRNCASECMP:
1521 if (!host_size_t_cst_p (arg2, &s2))
1522 return NULL_TREE;
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
1533 case CFN_BUILT_IN_BCMP:
1534 case CFN_BUILT_IN_MEMCMP:
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 if ((p0 = c_getstr (arg0, &s0))
1542 && (p1 = c_getstr (arg1, &s1))
1543 && s2 <= s0
1544 && s2 <= s1)
1545 return build_cmp_result (type, memcmp (p0, p1, s2));
1546 return NULL_TREE;
1547
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
1567 default:
1568 return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1569 }
1570 }
1571
1572 /* Fold a fma operation with arguments ARG[012]. */
1573
1574 tree
1575 fold_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 }