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 (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 case CFN_BUILT_IN_STRSTR: 1438 if ((p1 = c_getstr (arg1))) 1439 { 1440 if ((p0 = c_getstr (arg0))) 1441 { 1442 const char *r = strstr (p0, p1); 1443 if (r == NULL) 1444 return build_int_cst (type, 0); 1445 return fold_convert (type, 1446 fold_build_pointer_plus_hwi (arg0, r - p0)); 1447 } 1448 if (*p1 == '\0') 1449 return fold_convert (type, arg0); 1450 } 1451 return NULL_TREE; 1452 1453 default: 1454 return fold_const_call_1 (fn, type, arg0, arg1); 1455 } 1456 } 1457 1458 /* Try to evaluate: 1459 1460 *RESULT = FN (*ARG0, *ARG1, *ARG2) 1461 1462 in format FORMAT. Return true on success. */ 1463 1464 static bool 1465 fold_const_call_ssss (real_value *result, combined_fn fn, 1466 const real_value *arg0, const real_value *arg1, 1467 const real_value *arg2, const real_format *format) 1468 { 1469 switch (fn) 1470 { 1471 CASE_CFN_FMA: 1472 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format); 1473 1474 default: 1475 return false; 1476 } 1477 } 1478 1479 /* Subroutine of fold_const_call, with the same interface. Handle cases 1480 where the arguments and result are numerical. */ 1481 1482 static tree 1483 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) 1484 { 1485 machine_mode mode = TYPE_MODE (type); 1486 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); 1487 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1)); 1488 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2)); 1489 1490 if (arg0_mode == arg1_mode 1491 && arg0_mode == arg2_mode 1492 && real_cst_p (arg0) 1493 && real_cst_p (arg1) 1494 && real_cst_p (arg2)) 1495 { 1496 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); 1497 if (mode == arg0_mode) 1498 { 1499 /* real, real, real -> real. */ 1500 REAL_VALUE_TYPE result; 1501 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0), 1502 TREE_REAL_CST_PTR (arg1), 1503 TREE_REAL_CST_PTR (arg2), 1504 REAL_MODE_FORMAT (mode))) 1505 return build_real (type, result); 1506 } 1507 return NULL_TREE; 1508 } 1509 1510 return NULL_TREE; 1511 } 1512 1513 /* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on 1514 success, otherwise return null. TYPE is the type of the return value. */ 1515 1516 tree 1517 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) 1518 { 1519 const char *p0, *p1; 1520 char c; 1521 unsigned HOST_WIDE_INT s0, s1; 1522 size_t s2 = 0; 1523 switch (fn) 1524 { 1525 case CFN_BUILT_IN_STRNCMP: 1526 if (!host_size_t_cst_p (arg2, &s2)) 1527 return NULL_TREE; 1528 if (s2 == 0 1529 && !TREE_SIDE_EFFECTS (arg0) 1530 && !TREE_SIDE_EFFECTS (arg1)) 1531 return build_int_cst (type, 0); 1532 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) 1533 return build_int_cst (type, strncmp (p0, p1, s2)); 1534 return NULL_TREE; 1535 1536 case CFN_BUILT_IN_STRNCASECMP: 1537 if (!host_size_t_cst_p (arg2, &s2)) 1538 return NULL_TREE; 1539 if (s2 == 0 1540 && !TREE_SIDE_EFFECTS (arg0) 1541 && !TREE_SIDE_EFFECTS (arg1)) 1542 return build_int_cst (type, 0); 1543 else if ((p0 = c_getstr (arg0)) 1544 && (p1 = c_getstr (arg1)) 1545 && strncmp (p0, p1, s2) == 0) 1546 return build_int_cst (type, 0); 1547 return NULL_TREE; 1548 1549 case CFN_BUILT_IN_BCMP: 1550 case CFN_BUILT_IN_MEMCMP: 1551 if (!host_size_t_cst_p (arg2, &s2)) 1552 return NULL_TREE; 1553 if (s2 == 0 1554 && !TREE_SIDE_EFFECTS (arg0) 1555 && !TREE_SIDE_EFFECTS (arg1)) 1556 return build_int_cst (type, 0); 1557 if ((p0 = c_getstr (arg0, &s0)) 1558 && (p1 = c_getstr (arg1, &s1)) 1559 && s2 <= s0 1560 && s2 <= s1) 1561 return build_cmp_result (type, memcmp (p0, p1, s2)); 1562 return NULL_TREE; 1563 1564 case CFN_BUILT_IN_MEMCHR: 1565 if (!host_size_t_cst_p (arg2, &s2)) 1566 return NULL_TREE; 1567 if (s2 == 0 1568 && !TREE_SIDE_EFFECTS (arg0) 1569 && !TREE_SIDE_EFFECTS (arg1)) 1570 return build_int_cst (type, 0); 1571 if ((p0 = c_getstr (arg0, &s0)) 1572 && s2 <= s0 1573 && target_char_cst_p (arg1, &c)) 1574 { 1575 const char *r = (const char *) memchr (p0, c, s2); 1576 if (r == NULL) 1577 return build_int_cst (type, 0); 1578 return fold_convert (type, 1579 fold_build_pointer_plus_hwi (arg0, r - p0)); 1580 } 1581 return NULL_TREE; 1582 1583 default: 1584 return fold_const_call_1 (fn, type, arg0, arg1, arg2); 1585 } 1586 } 1587 1588 /* Fold a fma operation with arguments ARG[012]. */ 1589 1590 tree 1591 fold_fma (location_t, tree type, tree arg0, tree arg1, tree arg2) 1592 { 1593 REAL_VALUE_TYPE result; 1594 if (real_cst_p (arg0) 1595 && real_cst_p (arg1) 1596 && real_cst_p (arg2) 1597 && do_mpfr_arg3 (&result, mpfr_fma, TREE_REAL_CST_PTR (arg0), 1598 TREE_REAL_CST_PTR (arg1), TREE_REAL_CST_PTR (arg2), 1599 REAL_MODE_FORMAT (TYPE_MODE (type)))) 1600 return build_real (type, result); 1601 1602 return NULL_TREE; 1603 } 1604