...which simplifies the match.pd patterns I'm about to add. Bootstrapped & regression-tested on x86_64-linux-gnu. OK to install?
Thanks, Richard gcc/ * real.h (build_real_truncate): Declare. * real.c (build_real_truncate): New function. (strip_float_extensions): Use it. * builtins.c (fold_builtin_cabs, fold_builtin_sqrt, fold_builtin_cbrt) (fold_builtin_hypot, fold_builtin_pow): Likewise. * match.pd: Likewise. diff --git a/gcc/builtins.c b/gcc/builtins.c index 2ff1a8c..1751b37 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7593,12 +7593,10 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl) if (flag_unsafe_math_optimizations && operand_equal_p (real, imag, OEP_PURE_SAME)) { - const REAL_VALUE_TYPE sqrt2_trunc - = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ()); STRIP_NOPS (real); return fold_build2_loc (loc, MULT_EXPR, type, - fold_build1_loc (loc, ABS_EXPR, type, real), - build_real (type, sqrt2_trunc)); + fold_build1_loc (loc, ABS_EXPR, type, real), + build_real_truncate (type, dconst_sqrt2 ())); } } @@ -7757,8 +7755,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type) /* Adjust for the outer root. */ SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); - dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); - tree_root = build_real (type, dconstroot); + tree_root = build_real_truncate (type, dconstroot); return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); } } @@ -7805,11 +7802,9 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type) if (BUILTIN_EXPONENT_P (fcode)) { tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); - const REAL_VALUE_TYPE third_trunc = - real_value_truncate (TYPE_MODE (type), dconst_third ()); arg = fold_build2_loc (loc, MULT_EXPR, type, - CALL_EXPR_ARG (arg, 0), - build_real (type, third_trunc)); + CALL_EXPR_ARG (arg, 0), + build_real_truncate (type, dconst_third ())); return build_call_expr_loc (loc, expfn, 1, arg); } @@ -7825,8 +7820,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type) REAL_VALUE_TYPE dconstroot = dconst_third (); SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); - dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); - tree_root = build_real (type, dconstroot); + tree_root = build_real_truncate (type, dconstroot); return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); } } @@ -7846,8 +7840,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type) real_arithmetic (&dconstroot, MULT_EXPR, dconst_third_ptr (), dconst_third_ptr ()); - dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); - tree_root = build_real (type, dconstroot); + tree_root = build_real_truncate (type, dconstroot); return build_call_expr_loc (loc, powfn, 2, arg0, tree_root); } } @@ -7863,10 +7856,8 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type) if (tree_expr_nonnegative_p (arg00)) { tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); - const REAL_VALUE_TYPE dconstroot - = real_value_truncate (TYPE_MODE (type), dconst_third ()); - tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, - build_real (type, dconstroot)); + tree c = build_real_truncate (type, dconst_third ()); + tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, c); return build_call_expr_loc (loc, powfn, 2, arg00, narg01); } } @@ -8392,13 +8383,9 @@ fold_builtin_hypot (location_t loc, tree fndecl, /* hypot(x,x) -> fabs(x)*sqrt(2). */ if (flag_unsafe_math_optimizations && operand_equal_p (arg0, arg1, OEP_PURE_SAME)) - { - const REAL_VALUE_TYPE sqrt2_trunc - = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ()); - return fold_build2_loc (loc, MULT_EXPR, type, - fold_build1_loc (loc, ABS_EXPR, type, arg0), - build_real (type, sqrt2_trunc)); - } + return fold_build2_loc (loc, MULT_EXPR, type, + fold_build1_loc (loc, ABS_EXPR, type, arg0), + build_real_truncate (type, dconst_sqrt2 ())); return NULL_TREE; } @@ -8530,10 +8517,8 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type) tree arg = CALL_EXPR_ARG (arg0, 0); if (tree_expr_nonnegative_p (arg)) { - const REAL_VALUE_TYPE dconstroot - = real_value_truncate (TYPE_MODE (type), dconst_third ()); - tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, - build_real (type, dconstroot)); + tree c = build_real_truncate (type, dconst_third ()); + tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, c); return build_call_expr_loc (loc, fndecl, 2, arg, narg1); } } diff --git a/gcc/match.pd b/gcc/match.pd index bd5c267..d7f4e91 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2189,8 +2189,7 @@ along with GCC; see the file COPYING3. If not see { CASE_FLT_FN (BUILT_IN_EXP): /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */ - x = build_real (type, real_value_truncate (TYPE_MODE (type), - dconst_e ())); + x = build_real_truncate (type, dconst_e ()); break; CASE_FLT_FN (BUILT_IN_EXP2): /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ @@ -2226,8 +2225,7 @@ along with GCC; see the file COPYING3. If not see break; CASE_FLT_FN (BUILT_IN_CBRT): /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ - x = build_real (type, real_value_truncate (TYPE_MODE (type), - dconst_third ())); + x = build_real_truncate (type, dconst_third ()); break; default: gcc_unreachable (); diff --git a/gcc/real.h b/gcc/real.h index bd2a864..455d853 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -451,6 +451,9 @@ bool real_can_shorten_arithmetic (machine_mode, machine_mode); /* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node. */ extern tree build_real (tree, REAL_VALUE_TYPE); +/* Likewise, but first truncate the value to the type. */ +extern tree build_real_truncate (tree, REAL_VALUE_TYPE); + /* Calculate R as X raised to the integer exponent N in mode MODE. */ extern bool real_powi (REAL_VALUE_TYPE *, machine_mode, const REAL_VALUE_TYPE *, HOST_WIDE_INT); diff --git a/gcc/tree.c b/gcc/tree.c index 84fd34d..49c6285 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1877,6 +1877,14 @@ build_real (tree type, REAL_VALUE_TYPE d) return v; } +/* Like build_real, but first truncate D to the type. */ + +tree +build_real_truncate (tree type, REAL_VALUE_TYPE d) +{ + return build_real (type, real_value_truncate (TYPE_MODE (type), d)); +} + /* Return a new REAL_CST node whose type is TYPE and whose value is the integer value of the INTEGER_CST node I. */ @@ -12091,7 +12099,7 @@ strip_float_extensions (tree exp) && exact_real_truncate (TYPE_MODE (double_type_node), &orig)) type = double_type_node; if (type) - return build_real (type, real_value_truncate (TYPE_MODE (type), orig)); + return build_real_truncate (type, orig); } if (!CONVERT_EXPR_P (exp))