1 /* Constant folding for calls to built-in and internal functions. 2 Copyright (C) 1988-2020 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 #include "tree-vector-builder.h" 34 35 /* Functions that test for certain constant types, abstracting away the 36 decision about whether to check for overflow. */ 37 38 static inline bool 39 integer_cst_p (tree t) 40 { 41 return TREE_CODE (t) == INTEGER_CST && !TREE_OVERFLOW (t); 42 } 43 44 static inline bool 45 real_cst_p (tree t) 46 { 47 return TREE_CODE (t) == REAL_CST && !TREE_OVERFLOW (t); 48 } 49 50 static inline bool 51 complex_cst_p (tree t) 52 { 53 return TREE_CODE (t) == COMPLEX_CST; 54 } 55 56 /* Return true if ARG is a size_type_node constant. 57 Store it in *SIZE_OUT if so. */ 58 59 static inline bool 60 size_t_cst_p (tree t, unsigned HOST_WIDE_INT *size_out) 61 { 62 if (types_compatible_p (size_type_node, TREE_TYPE (t)) 63 && integer_cst_p (t) 64 && tree_fits_uhwi_p (t)) 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, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN; 133 mpfr_t m; 134 135 mpfr_init2 (m, prec); 136 mpfr_from_real (m, arg, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN; 163 mpfr_t m, ms, mc; 164 165 mpfr_inits2 (prec, m, ms, mc, NULL); 166 mpfr_from_real (m, arg, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN; 196 mpfr_t m0, m1; 197 198 mpfr_inits2 (prec, m0, m1, NULL); 199 mpfr_from_real (m0, arg0, MPFR_RNDN); 200 mpfr_from_real (m1, arg1, MPFR_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, mpfr_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN; 227 mpfr_t m; 228 229 mpfr_init2 (m, prec); 230 mpfr_from_real (m, arg1, MPFR_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 mpfr_rnd_t rnd = format->round_towards_zero ? MPFR_RNDZ : MPFR_RNDN; 263 mpfr_t m0, m1, m2; 264 265 mpfr_inits2 (prec, m0, m1, m2, NULL); 266 mpfr_from_real (m0, arg0, MPFR_RNDN); 267 mpfr_from_real (m1, arg1, MPFR_RNDN); 268 mpfr_from_real (m2, arg2, MPFR_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, MPFR_RNDN); 299 real_from_mpfr (&tmp_imag, mpc_imagref (m), format, MPFR_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, MPFR_RNDN); 344 mpfr_from_real (mpc_imagref (m), arg_imag, MPFR_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, MPFR_RNDN); 381 mpfr_from_real (mpc_imagref (m0), arg0_imag, MPFR_RNDN); 382 mpfr_from_real (mpc_realref (m1), arg1_real, MPFR_RNDN); 383 mpfr_from_real (mpc_imagref (m1), arg1_imag, MPFR_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 = nextafter (*ARG0, *ARG1) 533 534 or 535 536 *RESULT = nexttoward (*ARG0, *ARG1) 537 538 in format FORMAT. Return true on success. */ 539 540 static bool 541 fold_const_nextafter (real_value *result, const real_value *arg0, 542 const real_value *arg1, const real_format *format) 543 { 544 if (REAL_VALUE_ISSIGNALING_NAN (*arg0) 545 || REAL_VALUE_ISSIGNALING_NAN (*arg1)) 546 return false; 547 548 /* Don't handle composite modes, nor decimal, nor modes without 549 inf or denorm at least for now. */ 550 if (format->pnan < format->p 551 || format->b == 10 552 || !format->has_inf 553 || !format->has_denorm) 554 return false; 555 556 if (real_nextafter (result, format, arg0, arg1) 557 /* If raising underflow or overflow and setting errno to ERANGE, 558 fail if we care about those side-effects. */ 559 && (flag_trapping_math || flag_errno_math)) 560 return false; 561 /* Similarly for nextafter (0, 1) raising underflow. */ 562 else if (flag_trapping_math 563 && arg0->cl == rvc_zero 564 && result->cl != rvc_zero) 565 return false; 566 567 real_convert (result, format, result); 568 569 return true; 570 } 571 572 /* Try to evaluate: 573 574 *RESULT = ldexp (*ARG0, ARG1) 575 576 in format FORMAT. Return true on success. */ 577 578 static bool 579 fold_const_builtin_load_exponent (real_value *result, const real_value *arg0, 580 const wide_int_ref &arg1, 581 const real_format *format) 582 { 583 /* Bound the maximum adjustment to twice the range of the 584 mode's valid exponents. Use abs to ensure the range is 585 positive as a sanity check. */ 586 int max_exp_adj = 2 * labs (format->emax - format->emin); 587 588 /* The requested adjustment must be inside this range. This 589 is a preliminary cap to avoid things like overflow, we 590 may still fail to compute the result for other reasons. */ 591 if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj)) 592 return false; 593 594 /* Don't perform operation if we honor signaling NaNs and 595 operand is a signaling NaN. */ 596 if (!flag_unsafe_math_optimizations 597 && flag_signaling_nans 598 && REAL_VALUE_ISSIGNALING_NAN (*arg0)) 599 return false; 600 601 REAL_VALUE_TYPE initial_result; 602 real_ldexp (&initial_result, arg0, arg1.to_shwi ()); 603 604 /* Ensure we didn't overflow. */ 605 if (real_isinf (&initial_result)) 606 return false; 607 608 /* Only proceed if the target mode can hold the 609 resulting value. */ 610 *result = real_value_truncate (format, initial_result); 611 return real_equal (&initial_result, result); 612 } 613 614 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG and 615 return type TYPE. QUIET is true if a quiet rather than signalling 616 NaN is required. */ 617 618 static tree 619 fold_const_builtin_nan (tree type, tree arg, bool quiet) 620 { 621 REAL_VALUE_TYPE real; 622 const char *str = c_getstr (arg); 623 if (str && real_nan (&real, str, quiet, TYPE_MODE (type))) 624 return build_real (type, real); 625 return NULL_TREE; 626 } 627 628 /* Fold a call to IFN_REDUC_<CODE> (ARG), returning a value of type TYPE. */ 629 630 static tree 631 fold_const_reduction (tree type, tree arg, tree_code code) 632 { 633 unsigned HOST_WIDE_INT nelts; 634 if (TREE_CODE (arg) != VECTOR_CST 635 || !VECTOR_CST_NELTS (arg).is_constant (&nelts)) 636 return NULL_TREE; 637 638 tree res = VECTOR_CST_ELT (arg, 0); 639 for (unsigned HOST_WIDE_INT i = 1; i < nelts; i++) 640 { 641 res = const_binop (code, type, res, VECTOR_CST_ELT (arg, i)); 642 if (res == NULL_TREE || !CONSTANT_CLASS_P (res)) 643 return NULL_TREE; 644 } 645 return res; 646 } 647 648 /* Fold a call to IFN_VEC_CONVERT (ARG) returning TYPE. */ 649 650 static tree 651 fold_const_vec_convert (tree ret_type, tree arg) 652 { 653 enum tree_code code = NOP_EXPR; 654 tree arg_type = TREE_TYPE (arg); 655 if (TREE_CODE (arg) != VECTOR_CST) 656 return NULL_TREE; 657 658 gcc_checking_assert (VECTOR_TYPE_P (ret_type) && VECTOR_TYPE_P (arg_type)); 659 660 if (INTEGRAL_TYPE_P (TREE_TYPE (ret_type)) 661 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg_type))) 662 code = FIX_TRUNC_EXPR; 663 else if (INTEGRAL_TYPE_P (TREE_TYPE (arg_type)) 664 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (ret_type))) 665 code = FLOAT_EXPR; 666 667 /* We can't handle steps directly when extending, since the 668 values need to wrap at the original precision first. */ 669 bool step_ok_p 670 = (INTEGRAL_TYPE_P (TREE_TYPE (ret_type)) 671 && INTEGRAL_TYPE_P (TREE_TYPE (arg_type)) 672 && (TYPE_PRECISION (TREE_TYPE (ret_type)) 673 <= TYPE_PRECISION (TREE_TYPE (arg_type)))); 674 tree_vector_builder elts; 675 if (!elts.new_unary_operation (ret_type, arg, step_ok_p)) 676 return NULL_TREE; 677 678 unsigned int count = elts.encoded_nelts (); 679 for (unsigned int i = 0; i < count; ++i) 680 { 681 tree elt = fold_unary (code, TREE_TYPE (ret_type), 682 VECTOR_CST_ELT (arg, i)); 683 if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt)) 684 return NULL_TREE; 685 elts.quick_push (elt); 686 } 687 688 return elts.build (); 689 } 690 691 /* Try to evaluate: 692 693 IFN_WHILE_ULT (ARG0, ARG1, (TYPE) { ... }) 694 695 Return the value on success and null on failure. */ 696 697 static tree 698 fold_while_ult (tree type, poly_uint64 arg0, poly_uint64 arg1) 699 { 700 if (known_ge (arg0, arg1)) 701 return build_zero_cst (type); 702 703 if (maybe_ge (arg0, arg1)) 704 return NULL_TREE; 705 706 poly_uint64 diff = arg1 - arg0; 707 poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type); 708 if (known_ge (diff, nelts)) 709 return build_all_ones_cst (type); 710 711 unsigned HOST_WIDE_INT const_diff; 712 if (known_le (diff, nelts) && diff.is_constant (&const_diff)) 713 { 714 tree minus_one = build_minus_one_cst (TREE_TYPE (type)); 715 tree zero = build_zero_cst (TREE_TYPE (type)); 716 return build_vector_a_then_b (type, const_diff, minus_one, zero); 717 } 718 return NULL_TREE; 719 } 720 721 /* Try to evaluate: 722 723 *RESULT = FN (*ARG) 724 725 in format FORMAT. Return true on success. */ 726 727 static bool 728 fold_const_call_ss (real_value *result, combined_fn fn, 729 const real_value *arg, const real_format *format) 730 { 731 switch (fn) 732 { 733 CASE_CFN_SQRT: 734 CASE_CFN_SQRT_FN: 735 return (real_compare (GE_EXPR, arg, &dconst0) 736 && do_mpfr_arg1 (result, mpfr_sqrt, arg, format)); 737 738 CASE_CFN_CBRT: 739 return do_mpfr_arg1 (result, mpfr_cbrt, arg, format); 740 741 CASE_CFN_ASIN: 742 return (real_compare (GE_EXPR, arg, &dconstm1) 743 && real_compare (LE_EXPR, arg, &dconst1) 744 && do_mpfr_arg1 (result, mpfr_asin, arg, format)); 745 746 CASE_CFN_ACOS: 747 return (real_compare (GE_EXPR, arg, &dconstm1) 748 && real_compare (LE_EXPR, arg, &dconst1) 749 && do_mpfr_arg1 (result, mpfr_acos, arg, format)); 750 751 CASE_CFN_ATAN: 752 return do_mpfr_arg1 (result, mpfr_atan, arg, format); 753 754 CASE_CFN_ASINH: 755 return do_mpfr_arg1 (result, mpfr_asinh, arg, format); 756 757 CASE_CFN_ACOSH: 758 return (real_compare (GE_EXPR, arg, &dconst1) 759 && do_mpfr_arg1 (result, mpfr_acosh, arg, format)); 760 761 CASE_CFN_ATANH: 762 return (real_compare (GE_EXPR, arg, &dconstm1) 763 && real_compare (LE_EXPR, arg, &dconst1) 764 && do_mpfr_arg1 (result, mpfr_atanh, arg, format)); 765 766 CASE_CFN_SIN: 767 return do_mpfr_arg1 (result, mpfr_sin, arg, format); 768 769 CASE_CFN_COS: 770 return do_mpfr_arg1 (result, mpfr_cos, arg, format); 771 772 CASE_CFN_TAN: 773 return do_mpfr_arg1 (result, mpfr_tan, arg, format); 774 775 CASE_CFN_SINH: 776 return do_mpfr_arg1 (result, mpfr_sinh, arg, format); 777 778 CASE_CFN_COSH: 779 return do_mpfr_arg1 (result, mpfr_cosh, arg, format); 780 781 CASE_CFN_TANH: 782 return do_mpfr_arg1 (result, mpfr_tanh, arg, format); 783 784 CASE_CFN_ERF: 785 return do_mpfr_arg1 (result, mpfr_erf, arg, format); 786 787 CASE_CFN_ERFC: 788 return do_mpfr_arg1 (result, mpfr_erfc, arg, format); 789 790 CASE_CFN_TGAMMA: 791 return do_mpfr_arg1 (result, mpfr_gamma, arg, format); 792 793 CASE_CFN_EXP: 794 return do_mpfr_arg1 (result, mpfr_exp, arg, format); 795 796 CASE_CFN_EXP2: 797 return do_mpfr_arg1 (result, mpfr_exp2, arg, format); 798 799 CASE_CFN_EXP10: 800 CASE_CFN_POW10: 801 return do_mpfr_arg1 (result, mpfr_exp10, arg, format); 802 803 CASE_CFN_EXPM1: 804 return do_mpfr_arg1 (result, mpfr_expm1, arg, format); 805 806 CASE_CFN_LOG: 807 return (real_compare (GT_EXPR, arg, &dconst0) 808 && do_mpfr_arg1 (result, mpfr_log, arg, format)); 809 810 CASE_CFN_LOG2: 811 return (real_compare (GT_EXPR, arg, &dconst0) 812 && do_mpfr_arg1 (result, mpfr_log2, arg, format)); 813 814 CASE_CFN_LOG10: 815 return (real_compare (GT_EXPR, arg, &dconst0) 816 && do_mpfr_arg1 (result, mpfr_log10, arg, format)); 817 818 CASE_CFN_LOG1P: 819 return (real_compare (GT_EXPR, arg, &dconstm1) 820 && do_mpfr_arg1 (result, mpfr_log1p, arg, format)); 821 822 CASE_CFN_J0: 823 return do_mpfr_arg1 (result, mpfr_j0, arg, format); 824 825 CASE_CFN_J1: 826 return do_mpfr_arg1 (result, mpfr_j1, arg, format); 827 828 CASE_CFN_Y0: 829 return (real_compare (GT_EXPR, arg, &dconst0) 830 && do_mpfr_arg1 (result, mpfr_y0, arg, format)); 831 832 CASE_CFN_Y1: 833 return (real_compare (GT_EXPR, arg, &dconst0) 834 && do_mpfr_arg1 (result, mpfr_y1, arg, format)); 835 836 CASE_CFN_FLOOR: 837 CASE_CFN_FLOOR_FN: 838 if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) 839 { 840 real_floor (result, format, arg); 841 return true; 842 } 843 return false; 844 845 CASE_CFN_CEIL: 846 CASE_CFN_CEIL_FN: 847 if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) 848 { 849 real_ceil (result, format, arg); 850 return true; 851 } 852 return false; 853 854 CASE_CFN_TRUNC: 855 CASE_CFN_TRUNC_FN: 856 if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) 857 { 858 real_trunc (result, format, arg); 859 return true; 860 } 861 return false; 862 863 CASE_CFN_ROUND: 864 CASE_CFN_ROUND_FN: 865 if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) 866 { 867 real_round (result, format, arg); 868 return true; 869 } 870 return false; 871 872 CASE_CFN_ROUNDEVEN: 873 CASE_CFN_ROUNDEVEN_FN: 874 if (!REAL_VALUE_ISSIGNALING_NAN (*arg)) 875 { 876 real_roundeven (result, format, arg); 877 return true; 878 } 879 return false; 880 881 CASE_CFN_LOGB: 882 return fold_const_logb (result, arg, format); 883 884 CASE_CFN_SIGNIFICAND: 885 return fold_const_significand (result, arg, format); 886 887 default: 888 return false; 889 } 890 } 891 892 /* Try to evaluate: 893 894 *RESULT = FN (*ARG) 895 896 where FORMAT is the format of ARG and PRECISION is the number of 897 significant bits in the result. Return true on success. */ 898 899 static bool 900 fold_const_call_ss (wide_int *result, combined_fn fn, 901 const real_value *arg, unsigned int precision, 902 const real_format *format) 903 { 904 switch (fn) 905 { 906 CASE_CFN_SIGNBIT: 907 if (real_isneg (arg)) 908 *result = wi::one (precision); 909 else 910 *result = wi::zero (precision); 911 return true; 912 913 CASE_CFN_ILOGB: 914 /* For ilogb we don't know FP_ILOGB0, so only handle normal values. 915 Proceed iff radix == 2. In GCC, normalized significands are in 916 the range [0.5, 1.0). We want the exponent as if they were 917 [1.0, 2.0) so get the exponent and subtract 1. */ 918 if (arg->cl == rvc_normal && format->b == 2) 919 { 920 *result = wi::shwi (REAL_EXP (arg) - 1, precision); 921 return true; 922 } 923 return false; 924 925 CASE_CFN_ICEIL: 926 CASE_CFN_LCEIL: 927 CASE_CFN_LLCEIL: 928 return fold_const_conversion (result, real_ceil, arg, 929 precision, format); 930 931 CASE_CFN_LFLOOR: 932 CASE_CFN_IFLOOR: 933 CASE_CFN_LLFLOOR: 934 return fold_const_conversion (result, real_floor, arg, 935 precision, format); 936 937 CASE_CFN_IROUND: 938 CASE_CFN_LROUND: 939 CASE_CFN_LLROUND: 940 return fold_const_conversion (result, real_round, arg, 941 precision, format); 942 943 CASE_CFN_IRINT: 944 CASE_CFN_LRINT: 945 CASE_CFN_LLRINT: 946 /* Not yet folded to a constant. */ 947 return false; 948 949 CASE_CFN_FINITE: 950 case CFN_BUILT_IN_FINITED32: 951 case CFN_BUILT_IN_FINITED64: 952 case CFN_BUILT_IN_FINITED128: 953 case CFN_BUILT_IN_ISFINITE: 954 *result = wi::shwi (real_isfinite (arg) ? 1 : 0, precision); 955 return true; 956 957 CASE_CFN_ISINF: 958 case CFN_BUILT_IN_ISINFD32: 959 case CFN_BUILT_IN_ISINFD64: 960 case CFN_BUILT_IN_ISINFD128: 961 if (real_isinf (arg)) 962 *result = wi::shwi (arg->sign ? -1 : 1, precision); 963 else 964 *result = wi::shwi (0, precision); 965 return true; 966 967 CASE_CFN_ISNAN: 968 case CFN_BUILT_IN_ISNAND32: 969 case CFN_BUILT_IN_ISNAND64: 970 case CFN_BUILT_IN_ISNAND128: 971 *result = wi::shwi (real_isnan (arg) ? 1 : 0, precision); 972 return true; 973 974 default: 975 return false; 976 } 977 } 978 979 /* Try to evaluate: 980 981 *RESULT = FN (ARG) 982 983 where ARG_TYPE is the type of ARG and PRECISION is the number of bits 984 in the result. Return true on success. */ 985 986 static bool 987 fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg, 988 unsigned int precision, tree arg_type) 989 { 990 switch (fn) 991 { 992 CASE_CFN_FFS: 993 *result = wi::shwi (wi::ffs (arg), precision); 994 return true; 995 996 CASE_CFN_CLZ: 997 { 998 int tmp; 999 if (wi::ne_p (arg, 0)) 1000 tmp = wi::clz (arg); 1001 else if (!CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type), 1002 tmp)) 1003 tmp = TYPE_PRECISION (arg_type); 1004 *result = wi::shwi (tmp, precision); 1005 return true; 1006 } 1007 1008 CASE_CFN_CTZ: 1009 { 1010 int tmp; 1011 if (wi::ne_p (arg, 0)) 1012 tmp = wi::ctz (arg); 1013 else if (!CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (arg_type), 1014 tmp)) 1015 tmp = TYPE_PRECISION (arg_type); 1016 *result = wi::shwi (tmp, precision); 1017 return true; 1018 } 1019 1020 CASE_CFN_CLRSB: 1021 *result = wi::shwi (wi::clrsb (arg), precision); 1022 return true; 1023 1024 CASE_CFN_POPCOUNT: 1025 *result = wi::shwi (wi::popcount (arg), precision); 1026 return true; 1027 1028 CASE_CFN_PARITY: 1029 *result = wi::shwi (wi::parity (arg), precision); 1030 return true; 1031 1032 case CFN_BUILT_IN_BSWAP16: 1033 case CFN_BUILT_IN_BSWAP32: 1034 case CFN_BUILT_IN_BSWAP64: 1035 *result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap (); 1036 return true; 1037 1038 default: 1039 return false; 1040 } 1041 } 1042 1043 /* Try to evaluate: 1044 1045 RESULT = FN (*ARG) 1046 1047 where FORMAT is the format of ARG and of the real and imaginary parts 1048 of RESULT, passed as RESULT_REAL and RESULT_IMAG respectively. Return 1049 true on success. */ 1050 1051 static bool 1052 fold_const_call_cs (real_value *result_real, real_value *result_imag, 1053 combined_fn fn, const real_value *arg, 1054 const real_format *format) 1055 { 1056 switch (fn) 1057 { 1058 CASE_CFN_CEXPI: 1059 /* cexpi(x+yi) = cos(x)+sin(y)*i. */ 1060 return do_mpfr_sincos (result_imag, result_real, arg, format); 1061 1062 default: 1063 return false; 1064 } 1065 } 1066 1067 /* Try to evaluate: 1068 1069 *RESULT = fn (ARG) 1070 1071 where FORMAT is the format of RESULT and of the real and imaginary parts 1072 of ARG, passed as ARG_REAL and ARG_IMAG respectively. Return true on 1073 success. */ 1074 1075 static bool 1076 fold_const_call_sc (real_value *result, combined_fn fn, 1077 const real_value *arg_real, const real_value *arg_imag, 1078 const real_format *format) 1079 { 1080 switch (fn) 1081 { 1082 CASE_CFN_CABS: 1083 return do_mpfr_arg2 (result, mpfr_hypot, arg_real, arg_imag, format); 1084 1085 default: 1086 return false; 1087 } 1088 } 1089 1090 /* Try to evaluate: 1091 1092 RESULT = fn (ARG) 1093 1094 where FORMAT is the format of the real and imaginary parts of RESULT 1095 (RESULT_REAL and RESULT_IMAG) and of ARG (ARG_REAL and ARG_IMAG). 1096 Return true on success. */ 1097 1098 static bool 1099 fold_const_call_cc (real_value *result_real, real_value *result_imag, 1100 combined_fn fn, const real_value *arg_real, 1101 const real_value *arg_imag, const real_format *format) 1102 { 1103 switch (fn) 1104 { 1105 CASE_CFN_CCOS: 1106 return do_mpc_arg1 (result_real, result_imag, mpc_cos, 1107 arg_real, arg_imag, format); 1108 1109 CASE_CFN_CCOSH: 1110 return do_mpc_arg1 (result_real, result_imag, mpc_cosh, 1111 arg_real, arg_imag, format); 1112 1113 CASE_CFN_CPROJ: 1114 if (real_isinf (arg_real) || real_isinf (arg_imag)) 1115 { 1116 real_inf (result_real); 1117 *result_imag = dconst0; 1118 result_imag->sign = arg_imag->sign; 1119 } 1120 else 1121 { 1122 *result_real = *arg_real; 1123 *result_imag = *arg_imag; 1124 } 1125 return true; 1126 1127 CASE_CFN_CSIN: 1128 return do_mpc_arg1 (result_real, result_imag, mpc_sin, 1129 arg_real, arg_imag, format); 1130 1131 CASE_CFN_CSINH: 1132 return do_mpc_arg1 (result_real, result_imag, mpc_sinh, 1133 arg_real, arg_imag, format); 1134 1135 CASE_CFN_CTAN: 1136 return do_mpc_arg1 (result_real, result_imag, mpc_tan, 1137 arg_real, arg_imag, format); 1138 1139 CASE_CFN_CTANH: 1140 return do_mpc_arg1 (result_real, result_imag, mpc_tanh, 1141 arg_real, arg_imag, format); 1142 1143 CASE_CFN_CLOG: 1144 return do_mpc_arg1 (result_real, result_imag, mpc_log, 1145 arg_real, arg_imag, format); 1146 1147 CASE_CFN_CSQRT: 1148 return do_mpc_arg1 (result_real, result_imag, mpc_sqrt, 1149 arg_real, arg_imag, format); 1150 1151 CASE_CFN_CASIN: 1152 return do_mpc_arg1 (result_real, result_imag, mpc_asin, 1153 arg_real, arg_imag, format); 1154 1155 CASE_CFN_CACOS: 1156 return do_mpc_arg1 (result_real, result_imag, mpc_acos, 1157 arg_real, arg_imag, format); 1158 1159 CASE_CFN_CATAN: 1160 return do_mpc_arg1 (result_real, result_imag, mpc_atan, 1161 arg_real, arg_imag, format); 1162 1163 CASE_CFN_CASINH: 1164 return do_mpc_arg1 (result_real, result_imag, mpc_asinh, 1165 arg_real, arg_imag, format); 1166 1167 CASE_CFN_CACOSH: 1168 return do_mpc_arg1 (result_real, result_imag, mpc_acosh, 1169 arg_real, arg_imag, format); 1170 1171 CASE_CFN_CATANH: 1172 return do_mpc_arg1 (result_real, result_imag, mpc_atanh, 1173 arg_real, arg_imag, format); 1174 1175 CASE_CFN_CEXP: 1176 return do_mpc_arg1 (result_real, result_imag, mpc_exp, 1177 arg_real, arg_imag, format); 1178 1179 default: 1180 return false; 1181 } 1182 } 1183 1184 /* Subroutine of fold_const_call, with the same interface. Handle cases 1185 where the arguments and result are numerical. */ 1186 1187 static tree 1188 fold_const_call_1 (combined_fn fn, tree type, tree arg) 1189 { 1190 machine_mode mode = TYPE_MODE (type); 1191 machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg)); 1192 1193 if (integer_cst_p (arg)) 1194 { 1195 if (SCALAR_INT_MODE_P (mode)) 1196 { 1197 wide_int result; 1198 if (fold_const_call_ss (&result, fn, wi::to_wide (arg), 1199 TYPE_PRECISION (type), TREE_TYPE (arg))) 1200 return wide_int_to_tree (type, result); 1201 } 1202 return NULL_TREE; 1203 } 1204 1205 if (real_cst_p (arg)) 1206 { 1207 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode)); 1208 if (mode == arg_mode) 1209 { 1210 /* real -> real. */ 1211 REAL_VALUE_TYPE result; 1212 if (fold_const_call_ss (&result, fn, TREE_REAL_CST_PTR (arg), 1213 REAL_MODE_FORMAT (mode))) 1214 return build_real (type, result); 1215 } 1216 else if (COMPLEX_MODE_P (mode) 1217 && GET_MODE_INNER (mode) == arg_mode) 1218 { 1219 /* real -> complex real. */ 1220 REAL_VALUE_TYPE result_real, result_imag; 1221 if (fold_const_call_cs (&result_real, &result_imag, fn, 1222 TREE_REAL_CST_PTR (arg), 1223 REAL_MODE_FORMAT (arg_mode))) 1224 return build_complex (type, 1225 build_real (TREE_TYPE (type), result_real), 1226 build_real (TREE_TYPE (type), result_imag)); 1227 } 1228 else if (INTEGRAL_TYPE_P (type)) 1229 { 1230 /* real -> int. */ 1231 wide_int result; 1232 if (fold_const_call_ss (&result, fn, 1233 TREE_REAL_CST_PTR (arg), 1234 TYPE_PRECISION (type), 1235 REAL_MODE_FORMAT (arg_mode))) 1236 return wide_int_to_tree (type, result); 1237 } 1238 return NULL_TREE; 1239 } 1240 1241 if (complex_cst_p (arg)) 1242 { 1243 gcc_checking_assert (COMPLEX_MODE_P (arg_mode)); 1244 machine_mode inner_mode = GET_MODE_INNER (arg_mode); 1245 tree argr = TREE_REALPART (arg); 1246 tree argi = TREE_IMAGPART (arg); 1247 if (mode == arg_mode 1248 && real_cst_p (argr) 1249 && real_cst_p (argi)) 1250 { 1251 /* complex real -> complex real. */ 1252 REAL_VALUE_TYPE result_real, result_imag; 1253 if (fold_const_call_cc (&result_real, &result_imag, fn, 1254 TREE_REAL_CST_PTR (argr), 1255 TREE_REAL_CST_PTR (argi), 1256 REAL_MODE_FORMAT (inner_mode))) 1257 return build_complex (type, 1258 build_real (TREE_TYPE (type), result_real), 1259 build_real (TREE_TYPE (type), result_imag)); 1260 } 1261 if (mode == inner_mode 1262 && real_cst_p (argr) 1263 && real_cst_p (argi)) 1264 { 1265 /* complex real -> real. */ 1266 REAL_VALUE_TYPE result; 1267 if (fold_const_call_sc (&result, fn, 1268 TREE_REAL_CST_PTR (argr), 1269 TREE_REAL_CST_PTR (argi), 1270 REAL_MODE_FORMAT (inner_mode))) 1271 return build_real (type, result); 1272 } 1273 return NULL_TREE; 1274 } 1275 1276 return NULL_TREE; 1277 } 1278 1279 /* Try to fold FN (ARG) to a constant. Return the constant on success, 1280 otherwise return null. TYPE is the type of the return value. */ 1281 1282 tree 1283 fold_const_call (combined_fn fn, tree type, tree arg) 1284 { 1285 switch (fn) 1286 { 1287 case CFN_BUILT_IN_STRLEN: 1288 if (const char *str = c_getstr (arg)) 1289 return build_int_cst (type, strlen (str)); 1290 return NULL_TREE; 1291 1292 CASE_CFN_NAN: 1293 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NAN): 1294 case CFN_BUILT_IN_NAND32: 1295 case CFN_BUILT_IN_NAND64: 1296 case CFN_BUILT_IN_NAND128: 1297 return fold_const_builtin_nan (type, arg, true); 1298 1299 CASE_CFN_NANS: 1300 CASE_FLT_FN_FLOATN_NX (CFN_BUILT_IN_NANS): 1301 return fold_const_builtin_nan (type, arg, false); 1302 1303 case CFN_REDUC_PLUS: 1304 return fold_const_reduction (type, arg, PLUS_EXPR); 1305 1306 case CFN_REDUC_MAX: 1307 return fold_const_reduction (type, arg, MAX_EXPR); 1308 1309 case CFN_REDUC_MIN: 1310 return fold_const_reduction (type, arg, MIN_EXPR); 1311 1312 case CFN_REDUC_AND: 1313 return fold_const_reduction (type, arg, BIT_AND_EXPR); 1314 1315 case CFN_REDUC_IOR: 1316 return fold_const_reduction (type, arg, BIT_IOR_EXPR); 1317 1318 case CFN_REDUC_XOR: 1319 return fold_const_reduction (type, arg, BIT_XOR_EXPR); 1320 1321 case CFN_VEC_CONVERT: 1322 return fold_const_vec_convert (type, arg); 1323 1324 default: 1325 return fold_const_call_1 (fn, type, arg); 1326 } 1327 } 1328 1329 /* Fold a call to IFN_FOLD_LEFT_<CODE> (ARG0, ARG1), returning a value 1330 of type TYPE. */ 1331 1332 static tree 1333 fold_const_fold_left (tree type, tree arg0, tree arg1, tree_code code) 1334 { 1335 if (TREE_CODE (arg1) != VECTOR_CST) 1336 return NULL_TREE; 1337 1338 unsigned HOST_WIDE_INT nelts; 1339 if (!VECTOR_CST_NELTS (arg1).is_constant (&nelts)) 1340 return NULL_TREE; 1341 1342 for (unsigned HOST_WIDE_INT i = 0; i < nelts; i++) 1343 { 1344 arg0 = const_binop (code, type, arg0, VECTOR_CST_ELT (arg1, i)); 1345 if (arg0 == NULL_TREE || !CONSTANT_CLASS_P (arg0)) 1346 return NULL_TREE; 1347 } 1348 return arg0; 1349 } 1350 1351 /* Try to evaluate: 1352 1353 *RESULT = FN (*ARG0, *ARG1) 1354 1355 in format FORMAT. Return true on success. */ 1356 1357 static bool 1358 fold_const_call_sss (real_value *result, combined_fn fn, 1359 const real_value *arg0, const real_value *arg1, 1360 const real_format *format) 1361 { 1362 switch (fn) 1363 { 1364 CASE_CFN_DREM: 1365 CASE_CFN_REMAINDER: 1366 return do_mpfr_arg2 (result, mpfr_remainder, arg0, arg1, format); 1367 1368 CASE_CFN_ATAN2: 1369 return do_mpfr_arg2 (result, mpfr_atan2, arg0, arg1, format); 1370 1371 CASE_CFN_FDIM: 1372 return do_mpfr_arg2 (result, mpfr_dim, arg0, arg1, format); 1373 1374 CASE_CFN_HYPOT: 1375 return do_mpfr_arg2 (result, mpfr_hypot, arg0, arg1, format); 1376 1377 CASE_CFN_COPYSIGN: 1378 CASE_CFN_COPYSIGN_FN: 1379 *result = *arg0; 1380 real_copysign (result, arg1); 1381 return true; 1382 1383 CASE_CFN_FMIN: 1384 CASE_CFN_FMIN_FN: 1385 return do_mpfr_arg2 (result, mpfr_min, arg0, arg1, format); 1386 1387 CASE_CFN_FMAX: 1388 CASE_CFN_FMAX_FN: 1389 return do_mpfr_arg2 (result, mpfr_max, arg0, arg1, format); 1390 1391 CASE_CFN_POW: 1392 return fold_const_pow (result, arg0, arg1, format); 1393 1394 CASE_CFN_NEXTAFTER: 1395 CASE_CFN_NEXTTOWARD: 1396 return fold_const_nextafter (result, arg0, arg1, format); 1397 1398 default: 1399 return false; 1400 } 1401 } 1402 1403 /* Try to evaluate: 1404 1405 *RESULT = FN (*ARG0, ARG1) 1406 1407 where FORMAT is the format of *RESULT and *ARG0. Return true on 1408 success. */ 1409 1410 static bool 1411 fold_const_call_sss (real_value *result, combined_fn fn, 1412 const real_value *arg0, const wide_int_ref &arg1, 1413 const real_format *format) 1414 { 1415 switch (fn) 1416 { 1417 CASE_CFN_LDEXP: 1418 return fold_const_builtin_load_exponent (result, arg0, arg1, format); 1419 1420 CASE_CFN_SCALBN: 1421 CASE_CFN_SCALBLN: 1422 return (format->b == 2 1423 && fold_const_builtin_load_exponent (result, arg0, arg1, 1424 format)); 1425 1426 CASE_CFN_POWI: 1427 /* Avoid the folding if flag_signaling_nans is on and 1428 operand is a signaling NaN. */ 1429 if (!flag_unsafe_math_optimizations 1430 && flag_signaling_nans 1431 && REAL_VALUE_ISSIGNALING_NAN (*arg0)) 1432 return false; 1433 1434 real_powi (result, format, arg0, arg1.to_shwi ()); 1435 return true; 1436 1437 default: 1438 return false; 1439 } 1440 } 1441 1442 /* Try to evaluate: 1443 1444 *RESULT = FN (ARG0, *ARG1) 1445 1446 where FORMAT is the format of *RESULT and *ARG1. Return true on 1447 success. */ 1448 1449 static bool 1450 fold_const_call_sss (real_value *result, combined_fn fn, 1451 const wide_int_ref &arg0, const real_value *arg1, 1452 const real_format *format) 1453 { 1454 switch (fn) 1455 { 1456 CASE_CFN_JN: 1457 return do_mpfr_arg2 (result, mpfr_jn, arg0, arg1, format); 1458 1459 CASE_CFN_YN: 1460 return (real_compare (GT_EXPR, arg1, &dconst0) 1461 && do_mpfr_arg2 (result, mpfr_yn, arg0, arg1, format)); 1462 1463 default: 1464 return false; 1465 } 1466 } 1467 1468 /* Try to evaluate: 1469 1470 RESULT = fn (ARG0, ARG1) 1471 1472 where FORMAT is the format of the real and imaginary parts of RESULT 1473 (RESULT_REAL and RESULT_IMAG), of ARG0 (ARG0_REAL and ARG0_IMAG) 1474 and of ARG1 (ARG1_REAL and ARG1_IMAG). Return true on success. */ 1475 1476 static bool 1477 fold_const_call_ccc (real_value *result_real, real_value *result_imag, 1478 combined_fn fn, const real_value *arg0_real, 1479 const real_value *arg0_imag, const real_value *arg1_real, 1480 const real_value *arg1_imag, const real_format *format) 1481 { 1482 switch (fn) 1483 { 1484 CASE_CFN_CPOW: 1485 return do_mpc_arg2 (result_real, result_imag, mpc_pow, 1486 arg0_real, arg0_imag, arg1_real, arg1_imag, format); 1487 1488 default: 1489 return false; 1490 } 1491 } 1492 1493 /* Subroutine of fold_const_call, with the same interface. Handle cases 1494 where the arguments and result are numerical. */ 1495 1496 static tree 1497 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1) 1498 { 1499 machine_mode mode = TYPE_MODE (type); 1500 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); 1501 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1)); 1502 1503 if (mode == arg0_mode 1504 && real_cst_p (arg0) 1505 && real_cst_p (arg1)) 1506 { 1507 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); 1508 REAL_VALUE_TYPE result; 1509 if (arg0_mode == arg1_mode) 1510 { 1511 /* real, real -> real. */ 1512 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0), 1513 TREE_REAL_CST_PTR (arg1), 1514 REAL_MODE_FORMAT (mode))) 1515 return build_real (type, result); 1516 } 1517 else if (arg1_mode == TYPE_MODE (long_double_type_node)) 1518 switch (fn) 1519 { 1520 CASE_CFN_NEXTTOWARD: 1521 /* real, long double -> real. */ 1522 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0), 1523 TREE_REAL_CST_PTR (arg1), 1524 REAL_MODE_FORMAT (mode))) 1525 return build_real (type, result); 1526 break; 1527 default: 1528 break; 1529 } 1530 return NULL_TREE; 1531 } 1532 1533 if (real_cst_p (arg0) 1534 && integer_cst_p (arg1)) 1535 { 1536 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); 1537 if (mode == arg0_mode) 1538 { 1539 /* real, int -> real. */ 1540 REAL_VALUE_TYPE result; 1541 if (fold_const_call_sss (&result, fn, TREE_REAL_CST_PTR (arg0), 1542 wi::to_wide (arg1), 1543 REAL_MODE_FORMAT (mode))) 1544 return build_real (type, result); 1545 } 1546 return NULL_TREE; 1547 } 1548 1549 if (integer_cst_p (arg0) 1550 && real_cst_p (arg1)) 1551 { 1552 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg1_mode)); 1553 if (mode == arg1_mode) 1554 { 1555 /* int, real -> real. */ 1556 REAL_VALUE_TYPE result; 1557 if (fold_const_call_sss (&result, fn, wi::to_wide (arg0), 1558 TREE_REAL_CST_PTR (arg1), 1559 REAL_MODE_FORMAT (mode))) 1560 return build_real (type, result); 1561 } 1562 return NULL_TREE; 1563 } 1564 1565 if (arg0_mode == arg1_mode 1566 && complex_cst_p (arg0) 1567 && complex_cst_p (arg1)) 1568 { 1569 gcc_checking_assert (COMPLEX_MODE_P (arg0_mode)); 1570 machine_mode inner_mode = GET_MODE_INNER (arg0_mode); 1571 tree arg0r = TREE_REALPART (arg0); 1572 tree arg0i = TREE_IMAGPART (arg0); 1573 tree arg1r = TREE_REALPART (arg1); 1574 tree arg1i = TREE_IMAGPART (arg1); 1575 if (mode == arg0_mode 1576 && real_cst_p (arg0r) 1577 && real_cst_p (arg0i) 1578 && real_cst_p (arg1r) 1579 && real_cst_p (arg1i)) 1580 { 1581 /* complex real, complex real -> complex real. */ 1582 REAL_VALUE_TYPE result_real, result_imag; 1583 if (fold_const_call_ccc (&result_real, &result_imag, fn, 1584 TREE_REAL_CST_PTR (arg0r), 1585 TREE_REAL_CST_PTR (arg0i), 1586 TREE_REAL_CST_PTR (arg1r), 1587 TREE_REAL_CST_PTR (arg1i), 1588 REAL_MODE_FORMAT (inner_mode))) 1589 return build_complex (type, 1590 build_real (TREE_TYPE (type), result_real), 1591 build_real (TREE_TYPE (type), result_imag)); 1592 } 1593 return NULL_TREE; 1594 } 1595 1596 return NULL_TREE; 1597 } 1598 1599 /* Try to fold FN (ARG0, ARG1) to a constant. Return the constant on success, 1600 otherwise return null. TYPE is the type of the return value. */ 1601 1602 tree 1603 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1) 1604 { 1605 const char *p0, *p1; 1606 char c; 1607 switch (fn) 1608 { 1609 case CFN_BUILT_IN_STRSPN: 1610 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) 1611 return build_int_cst (type, strspn (p0, p1)); 1612 return NULL_TREE; 1613 1614 case CFN_BUILT_IN_STRCSPN: 1615 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) 1616 return build_int_cst (type, strcspn (p0, p1)); 1617 return NULL_TREE; 1618 1619 case CFN_BUILT_IN_STRCMP: 1620 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) 1621 return build_cmp_result (type, strcmp (p0, p1)); 1622 return NULL_TREE; 1623 1624 case CFN_BUILT_IN_STRCASECMP: 1625 if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) 1626 { 1627 int r = strcmp (p0, p1); 1628 if (r == 0) 1629 return build_cmp_result (type, r); 1630 } 1631 return NULL_TREE; 1632 1633 case CFN_BUILT_IN_INDEX: 1634 case CFN_BUILT_IN_STRCHR: 1635 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) 1636 { 1637 const char *r = strchr (p0, c); 1638 if (r == NULL) 1639 return build_int_cst (type, 0); 1640 return fold_convert (type, 1641 fold_build_pointer_plus_hwi (arg0, r - p0)); 1642 } 1643 return NULL_TREE; 1644 1645 case CFN_BUILT_IN_RINDEX: 1646 case CFN_BUILT_IN_STRRCHR: 1647 if ((p0 = c_getstr (arg0)) && target_char_cst_p (arg1, &c)) 1648 { 1649 const char *r = strrchr (p0, c); 1650 if (r == NULL) 1651 return build_int_cst (type, 0); 1652 return fold_convert (type, 1653 fold_build_pointer_plus_hwi (arg0, r - p0)); 1654 } 1655 return NULL_TREE; 1656 1657 case CFN_BUILT_IN_STRSTR: 1658 if ((p1 = c_getstr (arg1))) 1659 { 1660 if ((p0 = c_getstr (arg0))) 1661 { 1662 const char *r = strstr (p0, p1); 1663 if (r == NULL) 1664 return build_int_cst (type, 0); 1665 return fold_convert (type, 1666 fold_build_pointer_plus_hwi (arg0, r - p0)); 1667 } 1668 if (*p1 == '\0') 1669 return fold_convert (type, arg0); 1670 } 1671 return NULL_TREE; 1672 1673 case CFN_FOLD_LEFT_PLUS: 1674 return fold_const_fold_left (type, arg0, arg1, PLUS_EXPR); 1675 1676 default: 1677 return fold_const_call_1 (fn, type, arg0, arg1); 1678 } 1679 } 1680 1681 /* Try to evaluate: 1682 1683 *RESULT = FN (*ARG0, *ARG1, *ARG2) 1684 1685 in format FORMAT. Return true on success. */ 1686 1687 static bool 1688 fold_const_call_ssss (real_value *result, combined_fn fn, 1689 const real_value *arg0, const real_value *arg1, 1690 const real_value *arg2, const real_format *format) 1691 { 1692 switch (fn) 1693 { 1694 CASE_CFN_FMA: 1695 CASE_CFN_FMA_FN: 1696 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, arg2, format); 1697 1698 case CFN_FMS: 1699 { 1700 real_value new_arg2 = real_value_negate (arg2); 1701 return do_mpfr_arg3 (result, mpfr_fma, arg0, arg1, &new_arg2, format); 1702 } 1703 1704 case CFN_FNMA: 1705 { 1706 real_value new_arg0 = real_value_negate (arg0); 1707 return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1, arg2, format); 1708 } 1709 1710 case CFN_FNMS: 1711 { 1712 real_value new_arg0 = real_value_negate (arg0); 1713 real_value new_arg2 = real_value_negate (arg2); 1714 return do_mpfr_arg3 (result, mpfr_fma, &new_arg0, arg1, 1715 &new_arg2, format); 1716 } 1717 1718 default: 1719 return false; 1720 } 1721 } 1722 1723 /* Subroutine of fold_const_call, with the same interface. Handle cases 1724 where the arguments and result are numerical. */ 1725 1726 static tree 1727 fold_const_call_1 (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) 1728 { 1729 machine_mode mode = TYPE_MODE (type); 1730 machine_mode arg0_mode = TYPE_MODE (TREE_TYPE (arg0)); 1731 machine_mode arg1_mode = TYPE_MODE (TREE_TYPE (arg1)); 1732 machine_mode arg2_mode = TYPE_MODE (TREE_TYPE (arg2)); 1733 1734 if (arg0_mode == arg1_mode 1735 && arg0_mode == arg2_mode 1736 && real_cst_p (arg0) 1737 && real_cst_p (arg1) 1738 && real_cst_p (arg2)) 1739 { 1740 gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg0_mode)); 1741 if (mode == arg0_mode) 1742 { 1743 /* real, real, real -> real. */ 1744 REAL_VALUE_TYPE result; 1745 if (fold_const_call_ssss (&result, fn, TREE_REAL_CST_PTR (arg0), 1746 TREE_REAL_CST_PTR (arg1), 1747 TREE_REAL_CST_PTR (arg2), 1748 REAL_MODE_FORMAT (mode))) 1749 return build_real (type, result); 1750 } 1751 return NULL_TREE; 1752 } 1753 1754 return NULL_TREE; 1755 } 1756 1757 /* Try to fold FN (ARG0, ARG1, ARG2) to a constant. Return the constant on 1758 success, otherwise return null. TYPE is the type of the return value. */ 1759 1760 tree 1761 fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) 1762 { 1763 const char *p0, *p1; 1764 char c; 1765 unsigned HOST_WIDE_INT s0, s1, s2 = 0; 1766 switch (fn) 1767 { 1768 case CFN_BUILT_IN_STRNCMP: 1769 if (!size_t_cst_p (arg2, &s2)) 1770 return NULL_TREE; 1771 if (s2 == 0 1772 && !TREE_SIDE_EFFECTS (arg0) 1773 && !TREE_SIDE_EFFECTS (arg1)) 1774 return build_int_cst (type, 0); 1775 else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) 1776 return build_int_cst (type, strncmp (p0, p1, MIN (s2, SIZE_MAX))); 1777 return NULL_TREE; 1778 1779 case CFN_BUILT_IN_STRNCASECMP: 1780 if (!size_t_cst_p (arg2, &s2)) 1781 return NULL_TREE; 1782 if (s2 == 0 1783 && !TREE_SIDE_EFFECTS (arg0) 1784 && !TREE_SIDE_EFFECTS (arg1)) 1785 return build_int_cst (type, 0); 1786 else if ((p0 = c_getstr (arg0)) 1787 && (p1 = c_getstr (arg1)) 1788 && strncmp (p0, p1, MIN (s2, SIZE_MAX)) == 0) 1789 return build_int_cst (type, 0); 1790 return NULL_TREE; 1791 1792 case CFN_BUILT_IN_BCMP: 1793 case CFN_BUILT_IN_MEMCMP: 1794 if (!size_t_cst_p (arg2, &s2)) 1795 return NULL_TREE; 1796 if (s2 == 0 1797 && !TREE_SIDE_EFFECTS (arg0) 1798 && !TREE_SIDE_EFFECTS (arg1)) 1799 return build_int_cst (type, 0); 1800 if ((p0 = c_getstr (arg0, &s0)) 1801 && (p1 = c_getstr (arg1, &s1)) 1802 && s2 <= s0 1803 && s2 <= s1) 1804 return build_cmp_result (type, memcmp (p0, p1, s2)); 1805 return NULL_TREE; 1806 1807 case CFN_BUILT_IN_MEMCHR: 1808 if (!size_t_cst_p (arg2, &s2)) 1809 return NULL_TREE; 1810 if (s2 == 0 1811 && !TREE_SIDE_EFFECTS (arg0) 1812 && !TREE_SIDE_EFFECTS (arg1)) 1813 return build_int_cst (type, 0); 1814 if ((p0 = c_getstr (arg0, &s0)) 1815 && s2 <= s0 1816 && target_char_cst_p (arg1, &c)) 1817 { 1818 const char *r = (const char *) memchr (p0, c, s2); 1819 if (r == NULL) 1820 return build_int_cst (type, 0); 1821 return fold_convert (type, 1822 fold_build_pointer_plus_hwi (arg0, r - p0)); 1823 } 1824 return NULL_TREE; 1825 1826 case CFN_WHILE_ULT: 1827 { 1828 poly_uint64 parg0, parg1; 1829 if (poly_int_tree_p (arg0, &parg0) && poly_int_tree_p (arg1, &parg1)) 1830 return fold_while_ult (type, parg0, parg1); 1831 return NULL_TREE; 1832 } 1833 1834 default: 1835 return fold_const_call_1 (fn, type, arg0, arg1, arg2); 1836 } 1837 } 1838