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