diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2006-10-25 20:44:09 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2006-10-25 20:44:09 +0000 |
commit | cf1491f0e56e3d6ad918347fd05a2f953c9eede2 (patch) | |
tree | bcb317eaa0092ea0dc3d9db35118efcd9c04bc92 /gcc/builtins.c | |
parent | 4f0abdc91b8f1174b3dbd3660761e09b93e6d997 (diff) | |
download | gcc-cf1491f0e56e3d6ad918347fd05a2f953c9eede2.zip gcc-cf1491f0e56e3d6ad918347fd05a2f953c9eede2.tar.gz gcc-cf1491f0e56e3d6ad918347fd05a2f953c9eede2.tar.bz2 |
re PR middle-end/29335 (transcendental functions with constant arguments should be resolved at compile-time)
PR middle-end/29335
* builtins.c (fold_builtin_cbrt, fold_builtin_logarithm):
Calculate compile-time constants using MPFR.
(fold_builtin_1): Likewise handle BUILT_IN_ERF, BUILT_IN_ERFC,
BUILT_IN_EXPM1 and BUILT_IN_LOG1P.
testsuite:
* gcc.dg/torture/builtin-math-2.c (TESTIT): Use new helper macro.
Add checks for log, log2, log10 and log1p.
* gcc.dg/torture/builtin-math-3.c: Add checks for -0.0 everywhere
we already test 0.0. Add checks for expm1, log, log2, log10,
log1p, cbrt, erf and erfc.
From-SVN: r118042
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 1dcda03..694185d 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7110,13 +7110,14 @@ fold_builtin_cbrt (tree arglist, tree type) { tree arg = TREE_VALUE (arglist); const enum built_in_function fcode = builtin_mathfn_code (arg); + tree res; if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) return NULL_TREE; - /* Optimize cbrt of constant value. */ - if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg)) - return arg; + /* Calculate the result when the argument is a constant. */ + if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0))) + return res; if (flag_unsafe_math_optimizations) { @@ -7203,7 +7204,8 @@ fold_builtin_cbrt (tree arglist, tree type) static tree fold_builtin_cos (tree arglist, tree type, tree fndecl) { - tree arg = TREE_VALUE (arglist), res; + tree arg = TREE_VALUE (arglist); + tree res; if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) return NULL_TREE; @@ -7229,7 +7231,8 @@ static tree fold_builtin_tan (tree arglist, tree type) { enum built_in_function fcode; - tree arg = TREE_VALUE (arglist), res; + tree arg = TREE_VALUE (arglist); + tree res; if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) return NULL_TREE; @@ -7552,45 +7555,46 @@ real_dconstp (tree expr, const REAL_VALUE_TYPE *value) } /* A subroutine of fold_builtin to fold the various logarithmic - functions. EXP is the CALL_EXPR of a call to a builtin logN - function. VALUE is the base of the logN function. */ + functions. Return NULL_TREE if no simplification can me made. + FUNC is the corresponding MPFR logarithm function. */ static tree fold_builtin_logarithm (tree fndecl, tree arglist, - const REAL_VALUE_TYPE *value) + int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t)) { if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) { tree type = TREE_TYPE (TREE_TYPE (fndecl)); tree arg = TREE_VALUE (arglist); + tree res; const enum built_in_function fcode = builtin_mathfn_code (arg); - /* Optimize logN(1.0) = 0.0. */ - if (real_onep (arg)) - return build_real (type, dconst0); - - /* Optimize logN(N) = 1.0. If N can't be truncated to MODE - exactly, then only do this if flag_unsafe_math_optimizations. */ - if (exact_real_truncate (TYPE_MODE (type), value) - || flag_unsafe_math_optimizations) - { - const REAL_VALUE_TYPE value_truncate = - real_value_truncate (TYPE_MODE (type), *value); - if (real_dconstp (arg, &value_truncate)) + /* Optimize log(e) = 1.0. We're never passed an exact 'e', + instead we'll look for 'e' truncated to MODE. So only do + this if flag_unsafe_math_optimizations is set. */ + if (flag_unsafe_math_optimizations && func == mpfr_log) + { + const REAL_VALUE_TYPE e_truncated = + real_value_truncate (TYPE_MODE (type), dconste); + if (real_dconstp (arg, &e_truncated)) return build_real (type, dconst1); } + /* 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 - && ((value == &dconste + && ((func == mpfr_log && (fcode == BUILT_IN_EXP || fcode == BUILT_IN_EXPF || fcode == BUILT_IN_EXPL)) - || (value == &dconst2 + || (func == mpfr_log2 && (fcode == BUILT_IN_EXP2 || fcode == BUILT_IN_EXP2F || fcode == BUILT_IN_EXP2L)) - || (value == &dconst10 && (BUILTIN_EXP10_P (fcode))))) + || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode))))) return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1))); /* Optimize logN(func()) for various exponential functions. We @@ -7869,7 +7873,8 @@ fold_builtin_exponent (tree fndecl, tree arglist, if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) { tree type = TREE_TYPE (TREE_TYPE (fndecl)); - tree arg = TREE_VALUE (arglist), res; + tree arg = TREE_VALUE (arglist); + tree res; /* Calculate the result when the argument is a constant. */ if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0))) @@ -9040,6 +9045,18 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore) NULL, NULL, 0); break; + CASE_FLT_FN (BUILT_IN_ERF): + if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) + return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf, + NULL, NULL, 0); + break; + + CASE_FLT_FN (BUILT_IN_ERFC): + if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) + return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc, + NULL, NULL, 0); + break; + CASE_FLT_FN (BUILT_IN_EXP): return fold_builtin_exponent (fndecl, arglist, mpfr_exp); @@ -9050,14 +9067,26 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore) CASE_FLT_FN (BUILT_IN_POW10): return fold_builtin_exponent (fndecl, arglist, mpfr_exp10); + CASE_FLT_FN (BUILT_IN_EXPM1): + if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) + return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1, + NULL, NULL, 0); + break; + CASE_FLT_FN (BUILT_IN_LOG): - return fold_builtin_logarithm (fndecl, arglist, &dconste); + return fold_builtin_logarithm (fndecl, arglist, mpfr_log); CASE_FLT_FN (BUILT_IN_LOG2): - return fold_builtin_logarithm (fndecl, arglist, &dconst2); + return fold_builtin_logarithm (fndecl, arglist, mpfr_log2); CASE_FLT_FN (BUILT_IN_LOG10): - return fold_builtin_logarithm (fndecl, arglist, &dconst10); + return fold_builtin_logarithm (fndecl, arglist, mpfr_log10); + + CASE_FLT_FN (BUILT_IN_LOG1P): + if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) + return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p, + &dconstm1, NULL, false); + break; CASE_FLT_FN (BUILT_IN_POW): return fold_builtin_pow (fndecl, arglist, type); |