]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/fold-const-call.c
[34/77] Add a SCALAR_INT_TYPE_MODE macro
[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 (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 (SCALAR_INT_TYPE_MODE (arg_type),
848 tmp))
849 tmp = TYPE_PRECISION (arg_type);
850 *result = wi::shwi (tmp, precision);
851 return true;
852 }
853
854 CASE_CFN_CTZ:
855 {
856 int tmp;
857 if (wi::ne_p (arg, 0))
858 tmp = wi::ctz (arg);
859 else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type),
860 tmp))
861 tmp = TYPE_PRECISION (arg_type);
862 *result = wi::shwi (tmp, precision);
863 return true;
864 }
865
866 CASE_CFN_CLRSB:
867 *result = wi::shwi (wi::clrsb (arg), precision);
868 return true;
869
870 CASE_CFN_POPCOUNT:
871 *result = wi::shwi (wi::popcount (arg), precision);
872 return true;
873
874 CASE_CFN_PARITY:
875 *result = wi::shwi (wi::parity (arg), precision);
876 return true;
877
878 case CFN_BUILT_IN_BSWAP16:
879 case CFN_BUILT_IN_BSWAP32:
880 case CFN_BUILT_IN_BSWAP64:
881 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
882 return true;
883
884 default:
885 return false;
886 }
887 }
888
889 /* Try to evaluate:
890
891 RESULT = FN (*ARG)
892
893 where FORMAT is the format of ARG and of the real and imaginary parts
894 of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively. Return
895 true on success. */
896
897 static bool
898 fold_const_call_cs (real_value *result_real, real_value *result_imag,
899 combined_fn fn, const real_value *arg,
900 const real_format *format)
901 {
902 switch (fn)
903 {
904 CASE_CFN_CEXPI:
905 /* cexpi(x+yi) = cos(x)+sin(y)*i. */
906 return do_mpfr_sincos (result_imag, result_real, arg, format);
907
908 default:
909 return false;
910 }
911 }
912
913 /* Try to evaluate:
914
915 *RESULT = fn (ARG)
916
917 where FORMAT is the format of RESULT and of the real and imaginary parts
918 of ARG, passed as ARG_REAL and ARG_IMAG respectively. Return true on
919 success. */
920
921 static bool
922 fold_const_call_sc (real_value *result, combined_fn fn,
923 const real_value *arg_real, const real_value *arg_imag,
924 const real_format *format)
925 {
926 switch (fn)
927 {
928 CASE_CFN_CABS:
929 return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format);
930
931 default:
932 return false;
933 }
934 }
935
936 /* Try to evaluate:
937
938 RESULT = fn (ARG)
939
940 where FORMAT is the format of the real and imaginary parts of RESULT
941 (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG).
942 Return true on success. */
943
944 static bool
945 fold_const_call_cc (real_value *result_real, real_value *result_imag,
946 combined_fn fn, const real_value *arg_real,
947 const real_value *arg_imag, const real_format *format)
948 {
949 switch (fn)
950 {
951 CASE_CFN_CCOS:
952 return do_mpc_arg1 (result_real, result_imag, mpc_cos,
953 arg_real, arg_imag, format);
954
955 CASE_CFN_CCOSH:
956 return do_mpc_arg1 (result_real, result_imag, mpc_cosh,
957 arg_real, arg_imag, format);
958
959 CASE_CFN_CPROJ:
960 if (real_isinf (arg_real) || real_isinf (arg_imag))
961 {
962 real_inf (result_real);
963 *result_imag = dconst0;
964 result_imag->sign = arg_imag->sign;
965 }
966 else
967 {
968 *result_real = *arg_real;
969 *result_imag = *arg_imag;
970 }
971 return true;
972
973 CASE_CFN_CSIN:
974 return do_mpc_arg1 (result_real, result_imag, mpc_sin,
975 arg_real, arg_imag, format);
976
977 CASE_CFN_CSINH:
978 return do_mpc_arg1 (result_real, result_imag, mpc_sinh,
979 arg_real, arg_imag, format);
980
981 CASE_CFN_CTAN:
982 return do_mpc_arg1 (result_real, result_imag, mpc_tan,
983 arg_real, arg_imag, format);
984
985 CASE_CFN_CTANH:
986 return do_mpc_arg1 (result_real, result_imag, mpc_tanh,
987 arg_real, arg_imag, format);
988
989 CASE_CFN_CLOG:
990 return do_mpc_arg1 (result_real, result_imag, mpc_log,
991 arg_real, arg_imag, format);
992
993 CASE_CFN_CSQRT:
994 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt,
995 arg_real, arg_imag, format);
996
997 CASE_CFN_CASIN:
998 return do_mpc_arg1 (result_real, result_imag, mpc_asin,
999 arg_real, arg_imag, format);
1000
1001 CASE_CFN_CACOS:
1002 return do_mpc_arg1 (result_real, result_imag, mpc_acos,
1003 arg_real, arg_imag, format);
1004
1005 CASE_CFN_CATAN:
1006 return do_mpc_arg1 (result_real, result_imag, mpc_atan,
1007 arg_real, arg_imag, format);
1008
1009 CASE_CFN_CASINH:
1010 return do_mpc_arg1 (result_real, result_imag, mpc_asinh,
1011 arg_real, arg_imag, format);
1012
1013 CASE_CFN_CACOSH:
1014 return do_mpc_arg1 (result_real, result_imag, mpc_acosh,
1015 arg_real, arg_imag, format);
1016
1017 CASE_CFN_CATANH:
1018 return do_mpc_arg1 (result_real, result_imag, mpc_atanh,
1019 arg_real, arg_imag, format);
1020
1021 CASE_CFN_CEXP:
1022 return do_mpc_arg1 (result_real, result_imag, mpc_exp,
1023 arg_real, arg_imag, format);
1024
1025 default:
1026 return false;
1027 }
1028 }
1029
1030 /* Subroutine of fold_const_call, with the same interface. Handle cases
1031 where the arguments and result are numerical. */
1032
1033 static tree
1034 fold_const_call_1 (combined_fn fn, tree type, tree arg)
1035 {
1036 machine_mode mode = TYPE_MODE (type);
1037 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
1038
1039 if (integer_cst_p (arg))
1040 {
1041 if (SCALAR_INT_MODE_P (mode))
1042 {
1043 wide_int result;
1044 if (fold_const_call_ss (&result, fn, arg, TYPE_PRECISION (type),
1045 TREE_TYPE (arg)))
1046 return wide_int_to_tree (type, result);
1047 }
1048 return NULL_TREE;
1049 }
1050
1051 if (real_cst_p (arg))
1052 {
1053 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
1054 if (mode == arg_mode)
1055 {
1056 /* real -> real. */
1057 REAL_VALUE_TYPE result;
1058 if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg),
1059 REAL_MODE_FORMAT (mode)))
1060 return build_real (type, result);
1061 }
1062 else if (COMPLEX_MODE_P (mode)
1063 && GET_MODE_INNER (mode) == arg_mode)
1064 {
1065 /* real -> complex real. */
1066 REAL_VALUE_TYPE result_real, result_imag;
1067 if (fold_const_call_cs (&result_real, &result_imag, fn,
1068 TREE_REAL_CST_PTR (arg),
1069 REAL_MODE_FORMAT (arg_mode)))
1070 return build_complex (type,
1071 build_real (TREE_TYPE (type), result_real),
1072 build_real (TREE_TYPE (type), result_imag));
1073 }
1074 else if (INTEGRAL_TYPE_P (type))
1075 {
1076 /* real -> int. */
1077 wide_int result;
1078 if (fold_const_call_ss (&result, fn,
1079 TREE_REAL_CST_PTR (arg),
1080 TYPE_PRECISION (type),
1081 REAL_MODE_FORMAT (arg_mode)))
1082 return wide_int_to_tree (type, result);
1083 }
1084 return NULL_TREE;
1085 }
1086
1087 if (complex_cst_p (arg))
1088 {
1089 gcc_checking_assert (COMPLEX_MODE_P (arg_mode));
1090 machine_mode inner_mode = GET_MODE_INNER (arg_mode);
1091 tree argr = TREE_REALPART (arg);
1092 tree argi = TREE_IMAGPART (arg);
1093 if (mode == arg_mode
1094 && real_cst_p (argr)
1095 && real_cst_p (argi))
1096 {
1097 /* complex real -> complex real. */
1098 REAL_VALUE_TYPE result_real, result_imag;
1099 if (fold_const_call_cc (&result_real, &result_imag, fn,
1100 TREE_REAL_CST_PTR (argr),
1101 TREE_REAL_CST_PTR (argi),
1102 REAL_MODE_FORMAT (inner_mode)))
1103 return build_complex (type,
1104 build_real (TREE_TYPE (type), result_real),
1105 build_real (TREE_TYPE (type), result_imag));
1106 }
1107 if (mode == inner_mode
1108 && real_cst_p (argr)
1109 && real_cst_p (argi))
1110 {
1111 /* complex real -> real. */
1112 REAL_VALUE_TYPE result;
1113 if (fold_const_call_sc (&result, fn,
1114 TREE_REAL_CST_PTR (argr),
1115 TREE_REAL_CST_PTR (argi),
1116 REAL_MODE_FORMAT (inner_mode)))
1117 return build_real (type, result);
1118 }
1119 return NULL_TREE;
1120 }
1121
1122 return NULL_TREE;
1123 }
1124
1125 /* Try to fold FN (ARG) to a constant. Return the constant on success,
1126 otherwise return null. TYPE is the type of the return value. */
1127
1128 tree
1129 fold_const_call (combined_fn fn, tree type, tree arg)
1130 {
1131 switch (fn)
1132 {
1133 case CFN_BUILT_IN_STRLEN:
1134 if (const char *str = c_getstr (arg))
1135 return build_int_cst (type, strlen (str));
1136 return NULL_TREE;
1137
1138 CASE_CFN_NAN:
1139 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN):
1140 case CFN_BUILT_IN_NAND32:
1141 case CFN_BUILT_IN_NAND64:
1142 case CFN_BUILT_IN_NAND128:
1143 return fold_const_builtin_nan (type, arg, true);
1144
1145 CASE_CFN_NANS:
1146 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS):
1147 return fold_const_builtin_nan (type, arg, false);
1148
1149 default:
1150 return fold_const_call_1 (fn, type, arg);
1151 }
1152 }
1153
1154 /* Try to evaluate:
1155
1156 *RESULT = FN (*ARG0, *ARG1)
1157
1158 in format FORMAT. Return true on success. */
1159
1160 static bool
1161 fold_const_call_sss (real_value *result, combined_fn fn,
1162 const real_value *arg0, const real_value *arg1,
1163 const real_format *format)
1164 {
1165 switch (fn)
1166 {
1167 CASE_CFN_DREM:
1168 CASE_CFN_REMAINDER:
1169 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format);
1170
1171 CASE_CFN_ATAN2:
1172 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format);
1173
1174 CASE_CFN_FDIM:
1175 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format);
1176
1177 CASE_CFN_HYPOT:
1178 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format);
1179
1180 CASE_CFN_COPYSIGN:
1181 *result = *arg0;
1182 real_copysign (result, arg1);
1183 return true;
1184
1185 CASE_CFN_FMIN:
1186 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format);
1187
1188 CASE_CFN_FMAX:
1189 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format);
1190
1191 CASE_CFN_POW:
1192 return fold_const_pow (result, arg0, arg1, format);
1193
1194 default:
1195 return false;
1196 }
1197 }
1198
1199 /* Try to evaluate:
1200
1201 *RESULT = FN (*ARG0, ARG1)
1202
1203 where FORMAT is the format of *RESULT and *ARG0. Return true on
1204 success. */
1205
1206 static bool
1207 fold_const_call_sss (real_value *result, combined_fn fn,
1208 const real_value *arg0, const wide_int_ref &arg1,
1209 const real_format *format)
1210 {
1211 switch (fn)
1212 {
1213 CASE_CFN_LDEXP:
1214 return fold_const_builtin_load_exponent (result, arg0, arg1, format);
1215
1216 CASE_CFN_SCALBN:
1217 CASE_CFN_SCALBLN:
1218 return (format->b == 2
1219 && fold_const_builtin_load_exponent (result, arg0, arg1,
1220 format));
1221
1222 CASE_CFN_POWI:
1223 /* Avoid the folding if flag_signaling_nans is on and
1224 operand is a signaling NaN. */
1225 if (!flag_unsafe_math_optimizations
1226 && flag_signaling_nans
1227 && REAL_VALUE_ISSIGNALING_NAN (*arg0))
1228 return false;
1229
1230 real_powi (result, format, arg0, arg1.to_shwi ());
1231 return true;
1232
1233 default:
1234 return false;
1235 }
1236 }
1237
1238 /* Try to evaluate:
1239
1240 *RESULT = FN (ARG0, *ARG1)
1241
1242 where FORMAT is the format of *RESULT and *ARG1. Return true on
1243 success. */
1244
1245 static bool
1246 fold_const_call_sss (real_value *result, combined_fn fn,
1247 const wide_int_ref &arg0, const real_value *arg1,
1248 const real_format *format)
1249 {
1250 switch (fn)
1251 {
1252 CASE_CFN_JN:
1253 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format);
1254
1255 CASE_CFN_YN:
1256 return (real_compare (GT_EXPR, arg1, &dconst0)
1257 && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format));
1258
1259 default:
1260 return false;
1261 }
1262 }
1263
1264 /* Try to evaluate:
1265
1266 RESULT = fn (ARG0, ARG1)
1267
1268 where FORMAT is the format of the real and imaginary parts of RESULT
1269 (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG)
1270 and of ARG1 (ARG1_REAL and ARG1_IMAG). Return true on success. */
1271
1272 static bool
1273 fold_const_call_ccc (real_value *result_real, real_value *result_imag,
1274 combined_fn fn, const real_value *arg0_real,
1275 const real_value *arg0_imag, const real_value *arg1_real,
1276 const real_value *arg1_imag, const real_format *format)
1277 {
1278 switch (fn)
1279 {
1280 CASE_CFN_CPOW:
1281 return do_mpc_arg2 (result_real, result_imag, mpc_pow,
1282 arg0_real, arg0_imag, arg1_real, arg1_imag, format);
1283
1284 default:
1285 return false;
1286 }
1287 }
1288
1289 /* Subroutine of fold_const_call, with the same interface. Handle cases
1290 where the arguments and result are numerical. */
1291
1292 static tree
1293 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1)
1294 {
1295 machine_mode mode = TYPE_MODE (type);
1296 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1297 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1298
1299 if (arg0_mode == arg1_mode
1300 && real_cst_p (arg0)
1301 && real_cst_p (arg1))
1302 {
1303 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1304 if (mode == arg0_mode)
1305 {
1306 /* real, real -> real. */
1307 REAL_VALUE_TYPE result;
1308 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1309 TREE_REAL_CST_PTR (arg1),
1310 REAL_MODE_FORMAT (mode)))
1311 return build_real (type, result);
1312 }
1313 return NULL_TREE;
1314 }
1315
1316 if (real_cst_p (arg0)
1317 && integer_cst_p (arg1))
1318 {
1319 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1320 if (mode == arg0_mode)
1321 {
1322 /* real, int -> real. */
1323 REAL_VALUE_TYPE result;
1324 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0),
1325 arg1, REAL_MODE_FORMAT (mode)))
1326 return build_real (type, result);
1327 }
1328 return NULL_TREE;
1329 }
1330
1331 if (integer_cst_p (arg0)
1332 && real_cst_p (arg1))
1333 {
1334 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode));
1335 if (mode == arg1_mode)
1336 {
1337 /* int, real -> real. */
1338 REAL_VALUE_TYPE result;
1339 if (fold_const_call_sss (&result, fn, arg0,
1340 TREE_REAL_CST_PTR (arg1),
1341 REAL_MODE_FORMAT (mode)))
1342 return build_real (type, result);
1343 }
1344 return NULL_TREE;
1345 }
1346
1347 if (arg0_mode == arg1_mode
1348 && complex_cst_p (arg0)
1349 && complex_cst_p (arg1))
1350 {
1351 gcc_checking_assert (COMPLEX_MODE_P (arg0_mode));
1352 machine_mode inner_mode = GET_MODE_INNER (arg0_mode);
1353 tree arg0r = TREE_REALPART (arg0);
1354 tree arg0i = TREE_IMAGPART (arg0);
1355 tree arg1r = TREE_REALPART (arg1);
1356 tree arg1i = TREE_IMAGPART (arg1);
1357 if (mode == arg0_mode
1358 && real_cst_p (arg0r)
1359 && real_cst_p (arg0i)
1360 && real_cst_p (arg1r)
1361 && real_cst_p (arg1i))
1362 {
1363 /* complex real, complex real -> complex real. */
1364 REAL_VALUE_TYPE result_real, result_imag;
1365 if (fold_const_call_ccc (&result_real, &result_imag, fn,
1366 TREE_REAL_CST_PTR (arg0r),
1367 TREE_REAL_CST_PTR (arg0i),
1368 TREE_REAL_CST_PTR (arg1r),
1369 TREE_REAL_CST_PTR (arg1i),
1370 REAL_MODE_FORMAT (inner_mode)))
1371 return build_complex (type,
1372 build_real (TREE_TYPE (type), result_real),
1373 build_real (TREE_TYPE (type), result_imag));
1374 }
1375 return NULL_TREE;
1376 }
1377
1378 return NULL_TREE;
1379 }
1380
1381 /* Try to fold FN (ARG0, ARG1) to a constant. Return the constant on success,
1382 otherwise return null. TYPE is the type of the return value. */
1383
1384 tree
1385 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1)
1386 {
1387 const char *p0, *p1;
1388 char c;
1389 switch (fn)
1390 {
1391 case CFN_BUILT_IN_STRSPN:
1392 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1393 return build_int_cst (type, strspn (p0, p1));
1394 return NULL_TREE;
1395
1396 case CFN_BUILT_IN_STRCSPN:
1397 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1398 return build_int_cst (type, strcspn (p0, p1));
1399 return NULL_TREE;
1400
1401 case CFN_BUILT_IN_STRCMP:
1402 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1403 return build_cmp_result (type, strcmp (p0, p1));
1404 return NULL_TREE;
1405
1406 case CFN_BUILT_IN_STRCASECMP:
1407 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1408 {
1409 int r = strcmp (p0, p1);
1410 if (r == 0)
1411 return build_cmp_result (type, r);
1412 }
1413 return NULL_TREE;
1414
1415 case CFN_BUILT_IN_INDEX:
1416 case CFN_BUILT_IN_STRCHR:
1417 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1418 {
1419 const char *r = strchr (p0, c);
1420 if (r == NULL)
1421 return build_int_cst (type, 0);
1422 return fold_convert (type,
1423 fold_build_pointer_plus_hwi (arg0, r - p0));
1424 }
1425 return NULL_TREE;
1426
1427 case CFN_BUILT_IN_RINDEX:
1428 case CFN_BUILT_IN_STRRCHR:
1429 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c))
1430 {
1431 const char *r = strrchr (p0, c);
1432 if (r == NULL)
1433 return build_int_cst (type, 0);
1434 return fold_convert (type,
1435 fold_build_pointer_plus_hwi (arg0, r - p0));
1436 }
1437 return NULL_TREE;
1438
1439 case CFN_BUILT_IN_STRSTR:
1440 if ((p1 = c_getstr (arg1)))
1441 {
1442 if ((p0 = c_getstr (arg0)))
1443 {
1444 const char *r = strstr (p0, p1);
1445 if (r == NULL)
1446 return build_int_cst (type, 0);
1447 return fold_convert (type,
1448 fold_build_pointer_plus_hwi (arg0, r - p0));
1449 }
1450 if (*p1 == '\0')
1451 return fold_convert (type, arg0);
1452 }
1453 return NULL_TREE;
1454
1455 default:
1456 return fold_const_call_1 (fn, type, arg0, arg1);
1457 }
1458 }
1459
1460 /* Try to evaluate:
1461
1462 *RESULT = FN (*ARG0, *ARG1, *ARG2)
1463
1464 in format FORMAT. Return true on success. */
1465
1466 static bool
1467 fold_const_call_ssss (real_value *result, combined_fn fn,
1468 const real_value *arg0, const real_value *arg1,
1469 const real_value *arg2, const real_format *format)
1470 {
1471 switch (fn)
1472 {
1473 CASE_CFN_FMA:
1474 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format);
1475
1476 default:
1477 return false;
1478 }
1479 }
1480
1481 /* Subroutine of fold_const_call, with the same interface. Handle cases
1482 where the arguments and result are numerical. */
1483
1484 static tree
1485 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1486 {
1487 machine_mode mode = TYPE_MODE (type);
1488 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1489 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1));
1490 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2));
1491
1492 if (arg0_mode == arg1_mode
1493 && arg0_mode == arg2_mode
1494 && real_cst_p (arg0)
1495 && real_cst_p (arg1)
1496 && real_cst_p (arg2))
1497 {
1498 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode));
1499 if (mode == arg0_mode)
1500 {
1501 /* real, real, real -> real. */
1502 REAL_VALUE_TYPE result;
1503 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0),
1504 TREE_REAL_CST_PTR (arg1),
1505 TREE_REAL_CST_PTR (arg2),
1506 REAL_MODE_FORMAT (mode)))
1507 return build_real (type, result);
1508 }
1509 return NULL_TREE;
1510 }
1511
1512 return NULL_TREE;
1513 }
1514
1515 /* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on
1516 success, otherwise return null. TYPE is the type of the return value. */
1517
1518 tree
1519 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
1520 {
1521 const char *p0, *p1;
1522 char c;
1523 unsigned HOST_WIDE_INT s0, s1;
1524 size_t s2 = 0;
1525 switch (fn)
1526 {
1527 case CFN_BUILT_IN_STRNCMP:
1528 if (!host_size_t_cst_p (arg2, &s2))
1529 return NULL_TREE;
1530 if (s2 == 0
1531 && !TREE_SIDE_EFFECTS (arg0)
1532 && !TREE_SIDE_EFFECTS (arg1))
1533 return build_int_cst (type, 0);
1534 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)))
1535 return build_int_cst (type, strncmp (p0, p1, s2));
1536 return NULL_TREE;
1537
1538 case CFN_BUILT_IN_STRNCASECMP:
1539 if (!host_size_t_cst_p (arg2, &s2))
1540 return NULL_TREE;
1541 if (s2 == 0
1542 && !TREE_SIDE_EFFECTS (arg0)
1543 && !TREE_SIDE_EFFECTS (arg1))
1544 return build_int_cst (type, 0);
1545 else if ((p0 = c_getstr (arg0))
1546 && (p1 = c_getstr (arg1))
1547 && strncmp (p0, p1, s2) == 0)
1548 return build_int_cst (type, 0);
1549 return NULL_TREE;
1550
1551 case CFN_BUILT_IN_BCMP:
1552 case CFN_BUILT_IN_MEMCMP:
1553 if (!host_size_t_cst_p (arg2, &s2))
1554 return NULL_TREE;
1555 if (s2 == 0
1556 && !TREE_SIDE_EFFECTS (arg0)
1557 && !TREE_SIDE_EFFECTS (arg1))
1558 return build_int_cst (type, 0);
1559 if ((p0 = c_getstr (arg0, &s0))
1560 && (p1 = c_getstr (arg1, &s1))
1561 && s2 <= s0
1562 && s2 <= s1)
1563 return build_cmp_result (type, memcmp (p0, p1, s2));
1564 return NULL_TREE;
1565
1566 case CFN_BUILT_IN_MEMCHR:
1567 if (!host_size_t_cst_p (arg2, &s2))
1568 return NULL_TREE;
1569 if (s2 == 0
1570 && !TREE_SIDE_EFFECTS (arg0)
1571 && !TREE_SIDE_EFFECTS (arg1))
1572 return build_int_cst (type, 0);
1573 if ((p0 = c_getstr (arg0, &s0))
1574 && s2 <= s0
1575 && target_char_cst_p (arg1, &c))
1576 {
1577 const char *r = (const char *) memchr (p0, c, s2);
1578 if (r == NULL)
1579 return build_int_cst (type, 0);
1580 return fold_convert (type,
1581 fold_build_pointer_plus_hwi (arg0, r - p0));
1582 }
1583 return NULL_TREE;
1584
1585 default:
1586 return fold_const_call_1 (fn, type, arg0, arg1, arg2);
1587 }
1588 }
1589
1590 /* Fold a fma operation with arguments ARG[012]. */
1591
1592 tree
1593 fold_fma (location_t, tree type, tree arg0, tree arg1, tree arg2)
1594 {
1595 REAL_VALUE_TYPE result;
1596 if (real_cst_p (arg0)
1597 && real_cst_p (arg1)
1598 && real_cst_p (arg2)
1599 && do_mpfr_arg3 (&result, mpfr_fma, TREE_REAL_CST_PTR (arg0),
1600 TREE_REAL_CST_PTR (arg1), TREE_REAL_CST_PTR (arg2),
1601 REAL_MODE_FORMAT (TYPE_MODE (type))))
1602 return build_real (type, result);
1603
1604 return NULL_TREE;
1605 }