static bool fold_const_builtin_load_exponent (real_value *result, const real_value *arg0, const wide_int_ref &arg1, const real_format *format) { /* Bound the maximum adjustment to twice the range of the mode's valid exponents. Use abs to ensure the range is positive as a sanity check. */ int max_exp_adj = 2 * labs (format->emax - format->emin); /* The requested adjustment must be inside this range. This is a preliminary cap to avoid things like overflow, we may still fail to compute the result for other reasons. */ if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj)) return false; REAL_VALUE_TYPE initial_result; real_ldexp (&initial_result, arg0, arg1.to_shwi ()); /* Ensure we didn't overflow. */ if (real_isinf (&initial_result)) return false; /* Only proceed if the target mode can hold the resulting value. */ *result = real_value_truncate (format, initial_result); return real_equal (&initial_result, result); }
static bool fold_const_pow (real_value *result, const real_value *arg0, const real_value *arg1, const real_format *format) { if (do_mpfr_arg2 (result, mpfr_pow, arg0, arg1, format)) return true; /* Check for an integer exponent. */ REAL_VALUE_TYPE cint1; HOST_WIDE_INT n1 = real_to_integer (arg1); real_from_integer (&cint1, VOIDmode, n1, SIGNED); /* Attempt to evaluate pow at compile-time, unless this should raise an exception. */ if (real_identical (arg1, &cint1) && (n1 > 0 || (!flag_trapping_math && !flag_errno_math) || !real_equal (arg0, &dconst0))) { bool inexact = real_powi (result, format, arg0, n1); if (flag_unsafe_math_optimizations || !inexact) return true; } return false; }
int fr30_const_double_is_zero (rtx operand) { if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE) return 0; return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst0); }
static void gen_conditions_for_pow_cst_base (tree base, tree expn, vec<gimple *> conds, unsigned *nconds) { inp_domain exp_domain; /* Validate the range of the base constant to make sure it is consistent with check_pow. */ REAL_VALUE_TYPE mv; REAL_VALUE_TYPE bcv = TREE_REAL_CST (base); gcc_assert (!real_equal (&bcv, &dconst1) && !real_less (&bcv, &dconst1)); real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED); gcc_assert (!real_less (&mv, &bcv)); exp_domain = get_domain (0, false, false, 127, true, false); gen_conditions_for_domain (expn, exp_domain, conds, nconds); }
static bool check_pow (gcall *pow_call) { tree base, expn; enum tree_code bc, ec; if (gimple_call_num_args (pow_call) != 2) return false; base = gimple_call_arg (pow_call, 0); expn = gimple_call_arg (pow_call, 1); if (!check_target_format (expn)) return false; bc = TREE_CODE (base); ec = TREE_CODE (expn); /* Folding candidates are not interesting. Can actually assert that it is already folded. */ if (ec == REAL_CST && bc == REAL_CST) return false; if (bc == REAL_CST) { /* Only handle a fixed range of constant. */ REAL_VALUE_TYPE mv; REAL_VALUE_TYPE bcv = TREE_REAL_CST (base); if (real_equal (&bcv, &dconst1)) return false; if (real_less (&bcv, &dconst1)) return false; real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED); if (real_less (&mv, &bcv)) return false; return true; } else if (bc == SSA_NAME) { tree base_val0, type; gimple *base_def; int bit_sz; /* Only handles cases where base value is converted from integer values. */ base_def = SSA_NAME_DEF_STMT (base); if (gimple_code (base_def) != GIMPLE_ASSIGN) return false; if (gimple_assign_rhs_code (base_def) != FLOAT_EXPR) return false; base_val0 = gimple_assign_rhs1 (base_def); type = TREE_TYPE (base_val0); if (TREE_CODE (type) != INTEGER_TYPE) return false; bit_sz = TYPE_PRECISION (type); /* If the type of the base is too wide, the resulting shrink wrapping condition will be too conservative. */ if (bit_sz > MAX_BASE_INT_BIT_SIZE) return false; return true; } else return false; }
real restrict_value(real val, real region, real precise) { real right = (int)(val / region) * region; if (val && real_equal(val, right, precise)) return region; return val - right; }