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