re PR tree-optimization/14541 ([tree-ssa] built-in math functions are not fully optim...
authorRichard Biener <rguenther@suse.de>
Wed, 3 Dec 2014 11:55:14 +0000 (11:55 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 3 Dec 2014 11:55:14 +0000 (11:55 +0000)
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

gcc/ChangeLog
gcc/builtins.c
gcc/match.pd

index 566f68c3620e639caab6422ac4537a84fc4b2823..75b935b2e4b6892d64a2f518036b6000d4dde764 100644 (file)
@@ -1,3 +1,9 @@
+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
index 7766da7c448dbb60ac6bf895e0e208af8df9cb7d..b9dd664c9c2e18f16fcfff7e1e1b5a6b7cddf874 100644 (file)
@@ -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))
index 6c225b483d26226eabef41df42f5dc76671fe148..4bee62ef91c788897b7fd3aaa631c52ac3bf3410 100644 (file)
@@ -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)))))
+