Commit 52c6378a by Naveen H.S Committed by Naveen H.S

fold-const.c (fold_binary_loc): Move sqrt(x)*sqrt(x) as x to match.pd.

2015-08-21  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

	* fold-const.c (fold_binary_loc) : Move sqrt(x)*sqrt(x) as x
	to match.pd.
	Move Optimize pow(x,y)*pow(z,y) as pow(x*z,y)to match.pd.
	Move Optimize tan(x)*cos(x) as sin(x) to match.pd.
	Move Optimize x*pow(x,c) as pow(x,c+1) to match.pd.
	Move Optimize pow(x,c)*x as pow(x,c+1) to match.pd.
	Move Optimize sin(x)/cos(x) as tan(x) to match.pd.
	Move Optimize cos(x)/sin(x) as 1.0/tan(x) to match.pd.
	Move Optimize sin(x)/tan(x) as cos(x) to match.pd.
	Move Optimize tan(x)/sin(x) as 1.0/cos(x) to match.pd.
	Move Optimize pow(x,c)/x as pow(x,c-1) to match.pd.
	Move Optimize x/pow(y,z) into x*pow(y,-z) to match.pd.

	* match.pd (SIN ) : New Operator.
	(TAN) : New Operator.
	(mult (SQRT@1 @0) @1) : New simplifier.
	(mult (POW:s @0 @1) (POW:s @2 @1)) : New simplifier.
	(mult:c (TAN:s @0) (COS:s @0)) : New simplifier.
	(mult:c (TAN:s @0) (COS:s @0)) : New simplifier.
	(rdiv (SIN:s @0) (COS:s @0)) : New simplifier.
	(rdiv (COS:s @0) (SIN:s @0)) : New simplifier.
	(rdiv (SIN:s @0) (TAN:s @0)) : New simplifier.
	(rdiv (TAN:s @0) (SIN:s @0)) : New simplifier.
	(rdiv (POW:s @0 REAL_CST@1) @0) : New simplifier.
	(rdiv @0 (SQRT:s (rdiv:s @1 @2))) : New simplifier.
	(rdiv @0 (POW:s @1 @2)) : New simplifier.

From-SVN: r227056
parent eff1e5af
2015-08-21 Naveen H.S <Naveen.Hurugalawadi@caviumnetworks.com>
* fold-const.c (fold_binary_loc) : Move sqrt(x)*sqrt(x) as x
to match.pd.
Move Optimize pow(x,y)*pow(z,y) as pow(x*z,y)to match.pd.
Move Optimize tan(x)*cos(x) as sin(x) to match.pd.
Move Optimize x*pow(x,c) as pow(x,c+1) to match.pd.
Move Optimize pow(x,c)*x as pow(x,c+1) to match.pd.
Move Optimize sin(x)/cos(x) as tan(x) to match.pd.
Move Optimize cos(x)/sin(x) as 1.0/tan(x) to match.pd.
Move Optimize sin(x)/tan(x) as cos(x) to match.pd.
Move Optimize tan(x)/sin(x) as 1.0/cos(x) to match.pd.
Move Optimize pow(x,c)/x as pow(x,c-1) to match.pd.
Move Optimize x/pow(y,z) into x*pow(y,-z) to match.pd.
* match.pd (SIN ) : New Operator.
(TAN) : New Operator.
(mult (SQRT@1 @0) @1) : New simplifier.
(mult (POW:s @0 @1) (POW:s @2 @1)) : New simplifier.
(mult:c (TAN:s @0) (COS:s @0)) : New simplifier.
(mult:c (TAN:s @0) (COS:s @0)) : New simplifier.
(rdiv (SIN:s @0) (COS:s @0)) : New simplifier.
(rdiv (COS:s @0) (SIN:s @0)) : New simplifier.
(rdiv (SIN:s @0) (TAN:s @0)) : New simplifier.
(rdiv (TAN:s @0) (SIN:s @0)) : New simplifier.
(rdiv (POW:s @0 REAL_CST@1) @0) : New simplifier.
(rdiv @0 (SQRT:s (rdiv:s @1 @2))) : New simplifier.
(rdiv @0 (POW:s @1 @2)) : New simplifier.
2015-08-21 Bin Cheng <bin.cheng@arm.com> 2015-08-21 Bin Cheng <bin.cheng@arm.com>
* tree-ssa-loop-niter.c (simplify_using_initial_conditions): Break * tree-ssa-loop-niter.c (simplify_using_initial_conditions): Break
......
...@@ -9957,12 +9957,6 @@ fold_binary_loc (location_t loc, ...@@ -9957,12 +9957,6 @@ fold_binary_loc (location_t loc,
tree arg00 = CALL_EXPR_ARG (arg0, 0); tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg10 = CALL_EXPR_ARG (arg1, 0); tree arg10 = CALL_EXPR_ARG (arg1, 0);
/* Optimize sqrt(x)*sqrt(x) as x. */
if (BUILTIN_SQRT_P (fcode0)
&& operand_equal_p (arg00, arg10, 0)
&& ! HONOR_SNANS (element_mode (type)))
return arg00;
/* Optimize root(x)*root(y) as root(x*y). */ /* Optimize root(x)*root(y) as root(x*y). */
rootfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0); rootfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
arg = fold_build2_loc (loc, MULT_EXPR, type, arg00, arg10); arg = fold_build2_loc (loc, MULT_EXPR, type, arg00, arg10);
...@@ -9989,15 +9983,6 @@ fold_binary_loc (location_t loc, ...@@ -9989,15 +9983,6 @@ fold_binary_loc (location_t loc,
tree arg10 = CALL_EXPR_ARG (arg1, 0); tree arg10 = CALL_EXPR_ARG (arg1, 0);
tree arg11 = CALL_EXPR_ARG (arg1, 1); tree arg11 = CALL_EXPR_ARG (arg1, 1);
/* Optimize pow(x,y)*pow(z,y) as pow(x*z,y). */
if (operand_equal_p (arg01, arg11, 0))
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
tree arg = fold_build2_loc (loc, MULT_EXPR, type,
arg00, arg10);
return build_call_expr_loc (loc, powfn, 2, arg, arg01);
}
/* Optimize pow(x,y)*pow(x,z) as pow(x,y+z). */ /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z). */
if (operand_equal_p (arg00, arg10, 0)) if (operand_equal_p (arg00, arg10, 0))
{ {
...@@ -10008,67 +9993,6 @@ fold_binary_loc (location_t loc, ...@@ -10008,67 +9993,6 @@ fold_binary_loc (location_t loc,
} }
} }
/* Optimize tan(x)*cos(x) as sin(x). */
if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_COS)
|| (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_COSF)
|| (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_COSL)
|| (fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_TAN)
|| (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
|| (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
&& operand_equal_p (CALL_EXPR_ARG (arg0, 0),
CALL_EXPR_ARG (arg1, 0), 0))
{
tree sinfn = mathfn_built_in (type, BUILT_IN_SIN);
if (sinfn != NULL_TREE)
return build_call_expr_loc (loc, sinfn, 1,
CALL_EXPR_ARG (arg0, 0));
}
/* Optimize x*pow(x,c) as pow(x,c+1). */
if (fcode1 == BUILT_IN_POW
|| fcode1 == BUILT_IN_POWF
|| fcode1 == BUILT_IN_POWL)
{
tree arg10 = CALL_EXPR_ARG (arg1, 0);
tree arg11 = CALL_EXPR_ARG (arg1, 1);
if (TREE_CODE (arg11) == REAL_CST
&& !TREE_OVERFLOW (arg11)
&& operand_equal_p (arg0, arg10, 0))
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg1), 0);
REAL_VALUE_TYPE c;
tree arg;
c = TREE_REAL_CST (arg11);
real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
arg = build_real (type, c);
return build_call_expr_loc (loc, powfn, 2, arg0, arg);
}
}
/* Optimize pow(x,c)*x as pow(x,c+1). */
if (fcode0 == BUILT_IN_POW
|| fcode0 == BUILT_IN_POWF
|| fcode0 == BUILT_IN_POWL)
{
tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg01 = CALL_EXPR_ARG (arg0, 1);
if (TREE_CODE (arg01) == REAL_CST
&& !TREE_OVERFLOW (arg01)
&& operand_equal_p (arg1, arg00, 0))
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
REAL_VALUE_TYPE c;
tree arg;
c = TREE_REAL_CST (arg01);
real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
arg = build_real (type, c);
return build_call_expr_loc (loc, powfn, 2, arg1, arg);
}
}
/* Canonicalize x*x as pow(x,2.0), which is expanded as x*x. */ /* Canonicalize x*x as pow(x,2.0), which is expanded as x*x. */
if (!in_gimple_form if (!in_gimple_form
&& optimize && optimize
...@@ -10481,109 +10405,10 @@ fold_binary_loc (location_t loc, ...@@ -10481,109 +10405,10 @@ fold_binary_loc (location_t loc,
if (flag_unsafe_math_optimizations) if (flag_unsafe_math_optimizations)
{ {
enum built_in_function fcode0 = builtin_mathfn_code (arg0);
enum built_in_function fcode1 = builtin_mathfn_code (arg1); enum built_in_function fcode1 = builtin_mathfn_code (arg1);
/* Optimize sin(x)/cos(x) as tan(x). */
if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_COS)
|| (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
|| (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
&& operand_equal_p (CALL_EXPR_ARG (arg0, 0),
CALL_EXPR_ARG (arg1, 0), 0))
{
tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
if (tanfn != NULL_TREE)
return build_call_expr_loc (loc, tanfn, 1, CALL_EXPR_ARG (arg0, 0));
}
/* Optimize cos(x)/sin(x) as 1.0/tan(x). */
if (((fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_SIN)
|| (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
|| (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
&& operand_equal_p (CALL_EXPR_ARG (arg0, 0),
CALL_EXPR_ARG (arg1, 0), 0))
{
tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);
if (tanfn != NULL_TREE)
{
tree tmp = build_call_expr_loc (loc, tanfn, 1,
CALL_EXPR_ARG (arg0, 0));
return fold_build2_loc (loc, RDIV_EXPR, type,
build_real (type, dconst1), tmp);
}
}
/* Optimize sin(x)/tan(x) as cos(x) if we don't care about
NaNs or Infinities. */
if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_TAN)
|| (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_TANF)
|| (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_TANL)))
{
tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg01 = CALL_EXPR_ARG (arg1, 0);
if (! HONOR_NANS (arg00)
&& ! HONOR_INFINITIES (element_mode (arg00))
&& operand_equal_p (arg00, arg01, 0))
{
tree cosfn = mathfn_built_in (type, BUILT_IN_COS);
if (cosfn != NULL_TREE)
return build_call_expr_loc (loc, cosfn, 1, arg00);
}
}
/* Optimize tan(x)/sin(x) as 1.0/cos(x) if we don't care about
NaNs or Infinities. */
if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_SIN)
|| (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_SINF)
|| (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_SINL)))
{
tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg01 = CALL_EXPR_ARG (arg1, 0);
if (! HONOR_NANS (arg00)
&& ! HONOR_INFINITIES (element_mode (arg00))
&& operand_equal_p (arg00, arg01, 0))
{
tree cosfn = mathfn_built_in (type, BUILT_IN_COS);
if (cosfn != NULL_TREE)
{
tree tmp = build_call_expr_loc (loc, cosfn, 1, arg00);
return fold_build2_loc (loc, RDIV_EXPR, type,
build_real (type, dconst1),
tmp);
}
}
}
/* Optimize pow(x,c)/x as pow(x,c-1). */
if (fcode0 == BUILT_IN_POW
|| fcode0 == BUILT_IN_POWF
|| fcode0 == BUILT_IN_POWL)
{
tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg01 = CALL_EXPR_ARG (arg0, 1);
if (TREE_CODE (arg01) == REAL_CST
&& !TREE_OVERFLOW (arg01)
&& operand_equal_p (arg1, arg00, 0))
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
REAL_VALUE_TYPE c;
tree arg;
c = TREE_REAL_CST (arg01);
real_arithmetic (&c, MINUS_EXPR, &c, &dconst1);
arg = build_real (type, c);
return build_call_expr_loc (loc, powfn, 2, arg1, arg);
}
}
/* Optimize a/root(b/c) into a*root(c/b). */ /* Optimize a/root(b/c) into a*root(c/b). */
if (BUILTIN_ROOT_P (fcode1)) if (BUILTIN_CBRT_P (fcode1))
{ {
tree rootarg = CALL_EXPR_ARG (arg1, 0); tree rootarg = CALL_EXPR_ARG (arg1, 0);
...@@ -10611,19 +10436,6 @@ fold_binary_loc (location_t loc, ...@@ -10611,19 +10436,6 @@ fold_binary_loc (location_t loc,
return fold_build2_loc (loc, MULT_EXPR, type, arg0, arg1); return fold_build2_loc (loc, MULT_EXPR, type, arg0, arg1);
} }
/* Optimize x/pow(y,z) into x*pow(y,-z). */
if (fcode1 == BUILT_IN_POW
|| fcode1 == BUILT_IN_POWF
|| fcode1 == BUILT_IN_POWL)
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg1), 0);
tree arg10 = CALL_EXPR_ARG (arg1, 0);
tree arg11 = CALL_EXPR_ARG (arg1, 1);
tree neg11 = fold_convert_loc (loc, type,
negate_expr (arg11));
arg1 = build_call_expr_loc (loc, powfn, 2, arg10, neg11);
return fold_build2_loc (loc, MULT_EXPR, type, arg0, arg1);
}
} }
return NULL_TREE; return NULL_TREE;
......
...@@ -55,10 +55,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -55,10 +55,11 @@ along with GCC; see the file COPYING3. If not see
(define_operator_list POW10 BUILT_IN_POW10F BUILT_IN_POW10 BUILT_IN_POW10L) (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 SQRT BUILT_IN_SQRTF BUILT_IN_SQRT BUILT_IN_SQRTL)
(define_operator_list CBRT BUILT_IN_CBRTF BUILT_IN_CBRT BUILT_IN_CBRTL) (define_operator_list CBRT BUILT_IN_CBRTF BUILT_IN_CBRT BUILT_IN_CBRTL)
(define_operator_list SIN BUILT_IN_SIN BUILT_IN_SINL BUILT_IN_SINF)
(define_operator_list COS BUILT_IN_COS BUILT_IN_COSL BUILT_IN_COSF) (define_operator_list COS BUILT_IN_COS BUILT_IN_COSL BUILT_IN_COSF)
(define_operator_list TAN BUILT_IN_TAN BUILT_IN_TANL BUILT_IN_TANF)
(define_operator_list COSH BUILT_IN_COSH BUILT_IN_COSHL BUILT_IN_COSHF) (define_operator_list COSH BUILT_IN_COSH BUILT_IN_COSHL BUILT_IN_COSHF)
/* Simplifications of operations with one constant operand and /* Simplifications of operations with one constant operand and
simplifications to constants or single values. */ simplifications to constants or single values. */
...@@ -2006,6 +2007,69 @@ along with GCC; see the file COPYING3. If not see ...@@ -2006,6 +2007,69 @@ along with GCC; see the file COPYING3. If not see
/* fold_builtin_logarithm */ /* fold_builtin_logarithm */
(if (flag_unsafe_math_optimizations) (if (flag_unsafe_math_optimizations)
/* Simplify sqrt(x) * sqrt(x) -> x. */
(simplify
(mult (SQRT@1 @0) @1)
(if (!HONOR_SNANS (type))
@0))
/* Simplify pow(x,y) * pow(z,y) -> pow(x*z,y). */
(simplify
(mult (POW:s @0 @1) (POW:s @2 @1))
(POW (mult @0 @2) @1))
/* Simplify tan(x) * cos(x) -> sin(x). */
(simplify
(mult:c (TAN:s @0) (COS:s @0))
(SIN @0))
/* Simplify x * pow(x,c) -> pow(x,c+1). */
(simplify
(mult @0 (POW:s @0 REAL_CST@1))
(if (!TREE_OVERFLOW (@1))
(POW @0 (plus @1 { build_one_cst (type); }))))
/* Simplify sin(x) / cos(x) -> tan(x). */
(simplify
(rdiv (SIN:s @0) (COS:s @0))
(TAN @0))
/* Simplify cos(x) / sin(x) -> 1 / tan(x). */
(simplify
(rdiv (COS:s @0) (SIN:s @0))
(rdiv { build_one_cst (type); } (TAN @0)))
/* Simplify sin(x) / tan(x) -> cos(x). */
(simplify
(rdiv (SIN:s @0) (TAN:s @0))
(if (! HONOR_NANS (@0)
&& ! HONOR_INFINITIES (@0))
(cos @0)))
/* Simplify tan(x) / sin(x) -> 1.0 / cos(x). */
(simplify
(rdiv (TAN:s @0) (SIN:s @0))
(if (! HONOR_NANS (@0)
&& ! HONOR_INFINITIES (@0))
(rdiv { build_one_cst (type); } (COS @0))))
/* Simplify pow(x,c) / x -> pow(x,c-1). */
(simplify
(rdiv (POW:s @0 REAL_CST@1) @0)
(if (!TREE_OVERFLOW (@1))
(POW @0 (minus @1 { build_one_cst (type); }))))
/* Simplify a/root(b/c) into a*root(c/b). */
(simplify
(rdiv @0 (SQRT:s (rdiv:s @1 @2)))
(mult @0 (SQRT (rdiv @2 @1))))
/* Simplify x / pow (y,z) -> x * pow(y,-z). */
(simplify
(rdiv @0 (POW:s @1 @2))
(mult @0 (POW @1 (negate @2))))
/* Special case, optimize logN(expN(x)) = x. */ /* Special case, optimize logN(expN(x)) = x. */
(for logs (LOG LOG2 LOG10) (for logs (LOG LOG2 LOG10)
exps (EXP EXP2 EXP10) exps (EXP EXP2 EXP10)
......
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