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]

Re: [PATCH]: PR29335 use MPFR for two-argument math builtins (pow, atan2, hypot)


On Sun, 29 Oct 2006, Paolo Bonzini wrote:

>
> > Hmm... after some more thought I'm wondering don't I also need a fabs in
> > there?  I.e.:
> >
> > hypot(x,x) -> fabs(x)*sqrt(2)
>
> Yes, you do.
> Paolo

Okay this patch does three things.  Adds a check for
flag_unsafe_math_optimizations as suggested by Brad.  Fold ABS_EXPR in
arguments to hypot as suggested by Roger.  And third, add a fabs when
folding hypot(x,x).  I also added a few more wacky hypot testcases.

Tested on sparc-sun-solaris2.10, no regressions and all the new cases
pass.

Okay for mainline?

		Thanks,
		--Kaveh



2006-10-29  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* builtins.c (fold_builtin_hypot): Rearrange recursive
	transformation before others, and also do ABS_EXPR.  When
	necessary, check flag_unsafe_math_optimizations.  When necessary,
	add fabs.

testsuite:
	* gcc.dg/builtins-20.c: Add more hypot tests.

diff -rup orig/egcc-SVN20061028/gcc/builtins.c egcc-SVN20061028/gcc/builtins.c
--- orig/egcc-SVN20061028/gcc/builtins.c	2006-10-28 22:46:19.000000000 -0400
+++ egcc-SVN20061028/gcc/builtins.c	2006-10-29 00:05:13.803189590 -0400
@@ -7681,35 +7681,40 @@ fold_builtin_hypot (tree fndecl, tree ar
   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
     return res;

+  /* If either argument to hypot has a negate or abs, strip that off.
+     E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
+  if (TREE_CODE (arg0) == NEGATE_EXPR || TREE_CODE (arg1) == NEGATE_EXPR
+      || TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg1) == ABS_EXPR)
+    {
+      tree narg0 = (TREE_CODE (arg0) == NEGATE_EXPR
+		    || TREE_CODE (arg0) == ABS_EXPR)
+	? TREE_OPERAND (arg0, 0) : arg0;
+      tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR
+		    || TREE_CODE (arg1) == ABS_EXPR)
+	? TREE_OPERAND (arg1, 0) : arg1;
+      tree narglist = tree_cons (NULL_TREE, narg0,
+				 build_tree_list (NULL_TREE, narg1));
+      return build_function_call_expr (fndecl, narglist);
+    }
+
   /* If either argument is zero, hypot is fabs of the other.  */
   if (real_zerop (arg0))
     return fold_build1 (ABS_EXPR, type, arg1);
   else if (real_zerop (arg1))
     return fold_build1 (ABS_EXPR, type, arg0);

-  /* hypot(x,x) -> x*sqrt(2).  */
-  if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
+  /* hypot(x,x) -> fabs(x)*sqrt(2).  */
+  if (flag_unsafe_math_optimizations
+      && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
     {
       REAL_VALUE_TYPE sqrt2;

       real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
-      return fold_build2 (MULT_EXPR, type, arg0,
+      return fold_build2 (MULT_EXPR, type,
+			  fold_build1 (ABS_EXPR, type, arg0),
 			  build_real (type, sqrt2));
     }

-  /* Transform hypot(-x,y) or hypot(x,-y) or hypot(-x,-y) into
-     hypot(x,y).  */
-  if (TREE_CODE (arg0) == NEGATE_EXPR || TREE_CODE (arg1) == NEGATE_EXPR)
-    {
-      tree narg0 = (TREE_CODE (arg0) == NEGATE_EXPR)
-	? TREE_OPERAND (arg0, 0) : arg0;
-      tree narg1 = (TREE_CODE (arg1) == NEGATE_EXPR)
-	? TREE_OPERAND (arg1, 0) : arg1;
-      tree narglist = tree_cons (NULL_TREE, narg0,
-				 build_tree_list (NULL_TREE, narg1));
-      return build_function_call_expr (fndecl, narglist);
-    }
-
   return NULL_TREE;
 }

diff -rup orig/egcc-SVN20061028/gcc/testsuite/gcc.dg/builtins-20.c egcc-SVN20061028/gcc/testsuite/gcc.dg/builtins-20.c
--- orig/egcc-SVN20061028/gcc/testsuite/gcc.dg/builtins-20.c	2006-10-28 22:46:02.000000000 -0400
+++ egcc-SVN20061028/gcc/testsuite/gcc.dg/builtins-20.c	2006-10-29 00:15:57.229102443 -0400
@@ -16,14 +16,17 @@ extern double cos (double);
 extern double sin (double);
 extern double tan (double);
 extern double hypot (double, double);
+extern double pure (double) __attribute__ ((__pure__));
 extern float cosf (float);
 extern float sinf (float);
 extern float tanf (float);
 extern float hypotf (float, float);
+extern float puref (float) __attribute__ ((__pure__));
 extern long double cosl (long double);
 extern long double sinl (long double);
 extern long double tanl (long double);
 extern long double hypotl (long double, long double);
+extern long double purel (long double) __attribute__ ((__pure__));

 extern void link_error(void);

@@ -65,7 +68,7 @@ void test2(double x, double y)
   if (hypot (0, x) != __builtin_fabs(x))
     link_error ();

-  if (hypot (x, x) != x * __builtin_sqrt(2))
+  if (hypot (x, x) != __builtin_fabs(x) * __builtin_sqrt(2))
     link_error ();

   if (hypot (-x, y) != hypot (x, y))
@@ -76,6 +79,29 @@ void test2(double x, double y)

   if (hypot (-x, -y) != hypot (x, y))
     link_error ();
+
+  if (hypot (__builtin_fabs(x), y) != hypot (x, y))
+    link_error ();
+
+  if (hypot (x, __builtin_fabs(y)) != hypot (x, y))
+    link_error ();
+
+  if (hypot (__builtin_fabs(x), __builtin_fabs(y)) != hypot (x, y))
+    link_error ();
+
+  if (hypot (-__builtin_fabs(-x),
+	     -__builtin_fabs(__builtin_fabs(__builtin_fabs(-y))))
+      != hypot (x, y))
+    link_error ();
+
+  if (hypot (-x, 0) != __builtin_fabs(x))
+    link_error ();
+
+  if (hypot (-x, x) != __builtin_fabs(x) * __builtin_sqrt(2))
+    link_error ();
+
+  if (hypot (pure(x), -pure(x)) != __builtin_fabs(pure(x)) * __builtin_sqrt(2))
+    link_error ();
 }

 void test1f(float x)
@@ -118,7 +144,7 @@ void test2f(float x, float y)
   if (hypotf (0, x) != __builtin_fabsf(x))
     link_error ();

-  if (hypotf (x, x) != x * __builtin_sqrtf(2))
+  if (hypotf (x, x) != __builtin_fabsf(x) * __builtin_sqrtf(2))
     link_error ();

   if (hypotf (-x, y) != hypotf (x, y))
@@ -129,6 +155,29 @@ void test2f(float x, float y)

   if (hypotf (-x, -y) != hypotf (x, y))
     link_error ();
+
+  if (hypotf (__builtin_fabsf(x), y) != hypotf (x, y))
+    link_error ();
+
+  if (hypotf (x, __builtin_fabsf(y)) != hypotf (x, y))
+    link_error ();
+
+  if (hypotf (__builtin_fabsf(x), __builtin_fabsf(y)) != hypotf (x, y))
+    link_error ();
+
+  if (hypotf (-__builtin_fabsf(-x),
+	      -__builtin_fabsf(__builtin_fabsf(__builtin_fabsf(-y))))
+      != hypotf (x, y))
+    link_error ();
+
+  if (hypotf (-x, 0) != __builtin_fabsf(x))
+    link_error ();
+
+  if (hypotf (-x, x) != __builtin_fabsf(x) * __builtin_sqrtf(2))
+    link_error ();
+
+  if (hypotf (puref(x), -puref(x)) != __builtin_fabsf(puref(x)) * __builtin_sqrtf(2))
+    link_error ();
 }


@@ -172,7 +221,7 @@ void test2l(long double x, long double y
   if (hypotl (0, x) != __builtin_fabsl(x))
     link_error ();

-  if (hypotl (x, x) != x * __builtin_sqrtl(2))
+  if (hypotl (x, x) != __builtin_fabsl(x) * __builtin_sqrtl(2))
     link_error ();

   if (hypotl (-x, y) != hypotl (x, y))
@@ -183,6 +232,29 @@ void test2l(long double x, long double y

   if (hypotl (-x, -y) != hypotl (x, y))
     link_error ();
+
+  if (hypotl (__builtin_fabsl(x), y) != hypotl (x, y))
+    link_error ();
+
+  if (hypotl (x, __builtin_fabsl(y)) != hypotl (x, y))
+    link_error ();
+
+  if (hypotl (__builtin_fabsl(x), __builtin_fabsl(y)) != hypotl (x, y))
+    link_error ();
+
+  if (hypotl (-__builtin_fabsl(-x),
+	      -__builtin_fabsl(__builtin_fabsl(__builtin_fabsl(-y))))
+      != hypotl (x, y))
+    link_error ();
+
+  if (hypotl (-x, 0) != __builtin_fabsl(x))
+    link_error ();
+
+  if (hypotl (-x, x) != __builtin_fabsl(x) * __builtin_sqrtl(2))
+    link_error ();
+
+  if (hypotl (purel(x), -purel(x)) != __builtin_fabsl(purel(x)) * __builtin_sqrtl(2))
+    link_error ();
 }

 int main()


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