Commit e18c1d66 by Richard Biener Committed by Richard Biener

re PR tree-optimization/14541 ([tree-ssa] built-in math functions are not fully…

re PR tree-optimization/14541 ([tree-ssa] built-in math functions are not fully optimized at tree level)

2014-12-03  Richard Biener  <rguenther@suse.de>

	PR middle-end/14541
	* builtins.c (fold_builtin_logarithm): Implement simplifications ...
	* match.pd: ... here as patterns.

From-SVN: r218308
parent e43187ab
2014-12-03 Richard Biener <rguenther@suse.de>
PR middle-end/14541
* builtins.c (fold_builtin_logarithm): Implement simplifications ...
* match.pd: ... here as patterns.
2014-12-03 Prachi Godbole <prachi.godbole@imgtec.com>
* config/mips/p5600.md (define_automaton, define_cpu_unit): Replace
......@@ -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))
......
......@@ -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)))))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment