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