fold-const.c (fold_binary_loc): Move sqrt(x)*sqrt(x) as x to match.pd.
authorNaveen H.S <Naveen.Hurugalawadi@caviumnetworks.com>
Fri, 21 Aug 2015 10:46:09 +0000 (10:46 +0000)
committerNaveen H.S <naveenh@gcc.gnu.org>
Fri, 21 Aug 2015 10:46:09 +0000 (10:46 +0000)
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

gcc/ChangeLog
gcc/fold-const.c
gcc/match.pd

index cb1ed43..adacd43 100644 (file)
@@ -1,3 +1,32 @@
+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>
 
        * tree-ssa-loop-niter.c (simplify_using_initial_conditions): Break
index 93d6514..1e01726 100644 (file)
@@ -9957,12 +9957,6 @@ fold_binary_loc (location_t loc,
                  tree arg00 = CALL_EXPR_ARG (arg0, 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).  */
                  rootfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
                  arg = fold_build2_loc (loc, MULT_EXPR, type, arg00, arg10);
@@ -9989,15 +9983,6 @@ fold_binary_loc (location_t loc,
                  tree arg10 = CALL_EXPR_ARG (arg1, 0);
                  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).  */
                  if (operand_equal_p (arg00, arg10, 0))
                    {
@@ -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.  */
              if (!in_gimple_form
                  && optimize
@@ -10481,109 +10405,10 @@ fold_binary_loc (location_t loc,
 
       if (flag_unsafe_math_optimizations)
        {
-         enum built_in_function fcode0 = builtin_mathfn_code (arg0);
          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).  */
-         if (BUILTIN_ROOT_P (fcode1))
+         if (BUILTIN_CBRT_P (fcode1))
            {
              tree rootarg = CALL_EXPR_ARG (arg1, 0);
 
@@ -10611,19 +10436,6 @@ fold_binary_loc (location_t loc,
              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;
 
index 71f4127..eb0ba9d 100644 (file)
@@ -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 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 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 TAN BUILT_IN_TAN BUILT_IN_TANL BUILT_IN_TANF)
 (define_operator_list COSH BUILT_IN_COSH BUILT_IN_COSHL BUILT_IN_COSHF)
 
-
 /* Simplifications of operations with one constant operand and
    simplifications to constants or single values.  */
 
@@ -2006,6 +2007,69 @@ along with GCC; see the file COPYING3.  If not see
 
 /* fold_builtin_logarithm */
 (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.  */
  (for logs (LOG LOG2 LOG10)
       exps (EXP EXP2 EXP10)