From e18c1d66efcd143dff3ee5c1f1e0e5ef2bb8d2b8 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 3 Dec 2014 11:55:14 +0000 Subject: [PATCH] re PR tree-optimization/14541 ([tree-ssa] built-in math functions are not fully optimized at tree level) 2014-12-03 Richard Biener PR middle-end/14541 * builtins.c (fold_builtin_logarithm): Implement simplifications ... * match.pd: ... here as patterns. From-SVN: r218308 --- gcc/ChangeLog | 6 +++ gcc/builtins.c | 107 +++++-------------------------------------------- gcc/match.pd | 87 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 97 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 566f68c3620..75b935b2e4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-12-03 Richard Biener + + PR middle-end/14541 + * builtins.c (fold_builtin_logarithm): Implement simplifications ... + * match.pd: ... here as patterns. + 2014-12-03 Prachi Godbole * config/mips/p5600.md (define_automaton, define_cpu_unit): Replace diff --git a/gcc/builtins.c b/gcc/builtins.c index 7766da7c448..b9dd664c9c2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8375,99 +8375,6 @@ fold_builtin_bswap (tree fndecl, tree arg) return NULL_TREE; } -/* A subroutine of fold_builtin to fold the various logarithmic - functions. Return NULL_TREE if no simplification can me made. - FUNC is the corresponding MPFR logarithm function. */ - -static tree -fold_builtin_logarithm (location_t loc, tree fndecl, tree arg, - int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t)) -{ - if (validate_arg (arg, REAL_TYPE)) - { - tree type = TREE_TYPE (TREE_TYPE (fndecl)); - tree res; - const enum built_in_function fcode = builtin_mathfn_code (arg); - - /* Calculate the result when the argument is a constant. */ - if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false))) - return res; - - /* Special case, optimize logN(expN(x)) = x. */ - if (flag_unsafe_math_optimizations - && ((func == mpfr_log - && (fcode == BUILT_IN_EXP - || fcode == BUILT_IN_EXPF - || fcode == BUILT_IN_EXPL)) - || (func == mpfr_log2 - && (fcode == BUILT_IN_EXP2 - || fcode == BUILT_IN_EXP2F - || fcode == BUILT_IN_EXP2L)) - || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode))))) - return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0)); - - /* Optimize logN(func()) for various exponential functions. We - want to determine the value "x" and the power "exponent" in - order to transform logN(x**exponent) into exponent*logN(x). */ - if (flag_unsafe_math_optimizations) - { - tree exponent = 0, x = 0; - - switch (fcode) - { - 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 ())); - exponent = CALL_EXPR_ARG (arg, 0); - break; - CASE_FLT_FN (BUILT_IN_EXP2): - /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ - x = build_real (type, dconst2); - exponent = CALL_EXPR_ARG (arg, 0); - break; - CASE_FLT_FN (BUILT_IN_EXP10): - CASE_FLT_FN (BUILT_IN_POW10): - /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ - { - REAL_VALUE_TYPE dconst10; - real_from_integer (&dconst10, VOIDmode, 10, SIGNED); - x = build_real (type, dconst10); - } - exponent = CALL_EXPR_ARG (arg, 0); - break; - CASE_FLT_FN (BUILT_IN_SQRT): - /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */ - x = CALL_EXPR_ARG (arg, 0); - exponent = build_real (type, dconsthalf); - break; - CASE_FLT_FN (BUILT_IN_CBRT): - /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ - x = CALL_EXPR_ARG (arg, 0); - exponent = build_real (type, real_value_truncate (TYPE_MODE (type), - dconst_third ())); - break; - CASE_FLT_FN (BUILT_IN_POW): - /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */ - x = CALL_EXPR_ARG (arg, 0); - exponent = CALL_EXPR_ARG (arg, 1); - break; - default: - break; - } - - /* Now perform the optimization. */ - if (x && exponent) - { - tree logfn = build_call_expr_loc (loc, fndecl, 1, x); - return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn); - } - } - } - - return NULL_TREE; -} - /* Fold a builtin function call to hypot, hypotf, or hypotl. Return NULL_TREE if no simplification can be made. */ @@ -10226,16 +10133,22 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore) CASE_FLT_FN (BUILT_IN_EXPM1): if (validate_arg (arg0, REAL_TYPE)) return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0); - break; + break; CASE_FLT_FN (BUILT_IN_LOG): - return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log); + if (validate_arg (arg0, REAL_TYPE)) + return do_mpfr_arg1 (arg0, type, mpfr_log, &dconst0, NULL, false); + break; CASE_FLT_FN (BUILT_IN_LOG2): - return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2); + if (validate_arg (arg0, REAL_TYPE)) + return do_mpfr_arg1 (arg0, type, mpfr_log2, &dconst0, NULL, false); + break; CASE_FLT_FN (BUILT_IN_LOG10): - return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10); + if (validate_arg (arg0, REAL_TYPE)) + return do_mpfr_arg1 (arg0, type, mpfr_log10, &dconst0, NULL, false); + break; CASE_FLT_FN (BUILT_IN_LOG1P): if (validate_arg (arg0, REAL_TYPE)) diff --git a/gcc/match.pd b/gcc/match.pd index 6c225b483d2..4bee62ef91c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -918,3 +918,90 @@ along with GCC; see the file COPYING3. If not see (icmp @0 @1)) (if (ic == ncmp) (ncmp @0 @1))))) + + +/* Simplification of math builtins. */ + +(define_operator_list LOG BUILT_IN_LOGF BUILT_IN_LOG BUILT_IN_LOGL) +(define_operator_list EXP BUILT_IN_EXPF BUILT_IN_EXP BUILT_IN_EXPL) +(define_operator_list LOG2 BUILT_IN_LOG2F BUILT_IN_LOG2 BUILT_IN_LOG2L) +(define_operator_list EXP2 BUILT_IN_EXP2F BUILT_IN_EXP2 BUILT_IN_EXP2L) +(define_operator_list LOG10 BUILT_IN_LOG10F BUILT_IN_LOG10 BUILT_IN_LOG10L) +(define_operator_list EXP10 BUILT_IN_EXP10F BUILT_IN_EXP10 BUILT_IN_EXP10L) +(define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL) +(define_operator_list POW10 BUILT_IN_POW10F BUILT_IN_POW10 BUILT_IN_POW10L) +(define_operator_list SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL) +(define_operator_list CBRT BUILT_IN_CBRTF BUILT_IN_CBRT BUILT_IN_CBRTL) + + +/* fold_builtin_logarithm */ +(if (flag_unsafe_math_optimizations) + /* Special case, optimize logN(expN(x)) = x. */ + (for logs (LOG LOG2 LOG10) + exps (EXP EXP2 EXP10) + (simplify + (logs (exps @0)) + @0)) + /* Optimize logN(func()) for various exponential functions. We + want to determine the value "x" and the power "exponent" in + order to transform logN(x**exponent) into exponent*logN(x). */ + (for logs (LOG LOG LOG LOG + LOG2 LOG2 LOG2 LOG2 + LOG10 LOG10 LOG10 LOG10) + exps (EXP EXP2 EXP10 POW10) + (simplify + (logs (exps @0)) + (with { + tree x; + switch (exps) + { + 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 ())); + break; + CASE_FLT_FN (BUILT_IN_EXP2): + /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */ + x = build_real (type, dconst2); + break; + CASE_FLT_FN (BUILT_IN_EXP10): + CASE_FLT_FN (BUILT_IN_POW10): + /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ + { + REAL_VALUE_TYPE dconst10; + real_from_integer (&dconst10, VOIDmode, 10, SIGNED); + x = build_real (type, dconst10); + } + break; + } + } + (mult (logs { x; }) @0)))) + (for logs (LOG LOG + LOG2 LOG2 + LOG10 LOG10) + exps (SQRT CBRT) + (simplify + (logs (exps @0)) + (with { + tree x; + switch (exps) + { + CASE_FLT_FN (BUILT_IN_SQRT): + /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */ + x = build_real (type, dconsthalf); + 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 ())); + break; + } + } + (mult { x; } (logs @0))))) + /* logN(pow(x,exponent) -> exponent*logN(x). */ + (for logs (LOG LOG2 LOG10) + pows (POW) + (simplify + (logs (pows @0 @1)) + (mult @1 (logs @0))))) + -- 2.30.2