This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][2/n] Fix PR14541


This moves sqrt simplification from GENERIC to patterns.

The testcase adjustment shows one of the side-effects I mentioned
in 1/n - simplification is delayed to SSA and for the testcase
we have to trick CCP not folding everything to a constant before
the expression simplification is done in forwprops folding of all
statements.

Boostrap and regtest ongoing on x86_64-unknown-linux-gnu.

Richard.

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

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

	* gcc.dg/builtins-47.c: Adjust.

Index: gcc/match.pd
===================================================================
*** gcc/match.pd.orig	2014-12-03 12:50:07.645992434 +0100
--- gcc/match.pd	2014-12-03 13:01:55.332967931 +0100
*************** along with GCC; see the file COPYING3.
*** 1005,1007 ****
--- 1005,1034 ----
     (logs (pows @0 @1))
     (mult @1 (logs @0)))))
  
+ 
+ /* fold_builtin_sqrt */
+ (if (flag_unsafe_math_optimizations)
+  /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
+  (for expfn (EXP10 POW10 EXP EXP2)
+       sqrtfn (SQRT)
+   (simplify
+    (sqrtfn (expfn @0))
+    (expfn (mult @0 { build_real (type, dconsthalf); }))))
+  /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
+  (for rootfn (SQRT CBRT)
+       sqrtfn (SQRT)
+       powfn (POW)
+   (simplify
+    (sqrtfn (rootfn @0))
+    (with
+     { REAL_VALUE_TYPE dconstroot;
+       if (BUILTIN_SQRT_P (rootfn)) dconstroot = dconsthalf;
+       else dconstroot = dconst_third ();
+       /* Adjust for the outer root.  */
+       SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
+       dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); }
+     (powfn @0 { build_real (type, dconstroot); }))))
+  /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
+  (simplify
+   (SQRT (POW @0 @1))
+   (POW (abs @0) (mult @1 { build_real (TREE_TYPE (@1), dconsthalf); }))))
Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c.orig	2014-12-03 12:50:06.292992480 +0100
--- gcc/builtins.c	2014-12-03 13:01:55.335967931 +0100
*************** static bool integer_valued_real_p (tree)
*** 164,170 ****
  static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
  static rtx expand_builtin_fabs (tree, rtx, rtx);
  static rtx expand_builtin_signbit (tree, rtx);
- static tree fold_builtin_sqrt (location_t, tree, tree);
  static tree fold_builtin_cbrt (location_t, tree, tree);
  static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
  static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
--- 164,169 ----
*************** fold_builtin_cproj (location_t loc, tree
*** 7725,7804 ****
    return NULL_TREE;
  }
  
- /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
-    Return NULL_TREE if no simplification can be made.  */
- 
- static tree
- fold_builtin_sqrt (location_t loc, tree arg, tree type)
- {
- 
-   enum built_in_function fcode;
-   tree res;
- 
-   if (!validate_arg (arg, REAL_TYPE))
-     return NULL_TREE;
- 
-   /* Calculate the result when the argument is a constant.  */
-   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
-     return res;
- 
-   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
-   fcode = builtin_mathfn_code (arg);
-   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
-     {
-       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
-       arg = fold_build2_loc (loc, MULT_EXPR, type,
- 			 CALL_EXPR_ARG (arg, 0),
- 			 build_real (type, dconsthalf));
-       return build_call_expr_loc (loc, expfn, 1, arg);
-     }
- 
-   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
-   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
-     {
-       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
- 
-       if (powfn)
- 	{
- 	  tree arg0 = CALL_EXPR_ARG (arg, 0);
- 	  tree tree_root;
- 	  /* The inner root was either sqrt or cbrt.  */
- 	  /* This was a conditional expression but it triggered a bug
- 	     in Sun C 5.5.  */
- 	  REAL_VALUE_TYPE dconstroot;
- 	  if (BUILTIN_SQRT_P (fcode))
- 	    dconstroot = dconsthalf;
- 	  else
- 	    dconstroot = dconst_third ();
- 
- 	  /* Adjust for the outer root.  */
- 	  SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
- 	  dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
- 	  tree_root = build_real (type, dconstroot);
- 	  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
- 	}
-     }
- 
-   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
-   if (flag_unsafe_math_optimizations
-       && (fcode == BUILT_IN_POW
- 	  || fcode == BUILT_IN_POWF
- 	  || fcode == BUILT_IN_POWL))
-     {
-       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
-       tree arg0 = CALL_EXPR_ARG (arg, 0);
-       tree arg1 = CALL_EXPR_ARG (arg, 1);
-       tree narg1;
-       if (!tree_expr_nonnegative_p (arg0))
- 	arg0 = build1 (ABS_EXPR, type, arg0);
-       narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
- 			   build_real (type, dconsthalf));
-       return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
-     }
- 
-   return NULL_TREE;
- }
- 
  /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
     Return NULL_TREE if no simplification can be made.  */
  
--- 7724,7729 ----
*************** fold_builtin_1 (location_t loc, tree fnd
*** 10035,10041 ****
        return fold_builtin_carg (loc, arg0, type);
  
      CASE_FLT_FN (BUILT_IN_SQRT):
!       return fold_builtin_sqrt (loc, arg0, type);
  
      CASE_FLT_FN (BUILT_IN_CBRT):
        return fold_builtin_cbrt (loc, arg0, type);
--- 9960,9968 ----
        return fold_builtin_carg (loc, arg0, type);
  
      CASE_FLT_FN (BUILT_IN_SQRT):
!       if (validate_arg (arg0, REAL_TYPE))
!         return do_mpfr_arg1 (arg0, type, mpfr_sqrt, &dconst0, NULL, true);
!       break;
  
      CASE_FLT_FN (BUILT_IN_CBRT):
        return fold_builtin_cbrt (loc, arg0, type);
Index: gcc/testsuite/gcc.dg/builtins-47.c
===================================================================
*** gcc/testsuite/gcc.dg/builtins-47.c.orig	2011-10-10 16:22:07.000000000 +0200
--- gcc/testsuite/gcc.dg/builtins-47.c	2014-12-03 13:26:32.379916791 +0100
***************
*** 1,13 ****
  /* { dg-do run } */
! /* { dg-options "-O -ffast-math -fdump-tree-gimple" } */
  
  extern double sqrt (double);
  extern double pow (double, double);
  extern void abort (void);
  
  int main ()
  {
-   double x = -1.0;
    if (sqrt (pow (x, 2)) != 1.0)
      abort();
    if (sqrt (x*x) != 1.0)
--- 1,14 ----
  /* { dg-do run } */
! /* { dg-options "-O -ffast-math -fdump-tree-cddce1" } */
  
  extern double sqrt (double);
  extern double pow (double, double);
  extern void abort (void);
  
+ double x = -1.0;
+ 
  int main ()
  {
    if (sqrt (pow (x, 2)) != 1.0)
      abort();
    if (sqrt (x*x) != 1.0)
*************** int main ()
*** 15,20 ****
    return 0;
  }
  
! /* { dg-final { scan-tree-dump-times "sqrt" 0 "gimple" } } */
! /* { dg-final { scan-tree-dump-times "pow" 0 "gimple" } } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */
--- 16,21 ----
    return 0;
  }
  
! /* { dg-final { scan-tree-dump-times "sqrt" 0 "cddce1" } } */
! /* { dg-final { scan-tree-dump-times "pow" 0 "cddce1" } } */
  /* { dg-final { cleanup-tree-dump "gimple" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]