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]: Handle builtin copysign in fold_strip_sign_ops


Minor update to handle builtin copysign in fold_strip_sign_ops.

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

Okay for mainline?

		Thanks,
		--Kaveh


2006-11-13  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* fold-const.c (fold_strip_sign_ops): Handle copysign.

testsuite:
	* gcc.dg/builtins-20.c: Add cases for copysign.

diff -rup orig/egcc-SVN20061112/gcc/fold-const.c egcc-SVN20061112/gcc/fold-const.c
--- orig/egcc-SVN20061112/gcc/fold-const.c	2006-11-13 19:04:32.259234027 -0500
+++ egcc-SVN20061112/gcc/fold-const.c	2006-11-13 19:13:43.588796020 -0500
@@ -13377,14 +13377,29 @@ fold_strip_sign_ops (tree exp)
       break;

     case CALL_EXPR:
-      /* Strip sign ops from the argument of "odd" math functions.  */
-      if (negate_mathfn_p (builtin_mathfn_code (exp)))
-        {
-	  arg0 = fold_strip_sign_ops (TREE_VALUE (TREE_OPERAND (exp, 1)));
-	  if (arg0)
-	    return build_function_call_expr (get_callee_fndecl (exp),
-					     build_tree_list (NULL_TREE, arg0));
+      {
+	const enum built_in_function fcode = builtin_mathfn_code (exp);
+	switch (fcode)
+	{
+	CASE_FLT_FN (BUILT_IN_COPYSIGN):
+	  /* Strip copysign function call, return the 1st argument. */
+	  arg0 = TREE_VALUE (TREE_OPERAND (exp, 1));
+	  arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (exp, 1)));
+	  return omit_one_operand (TREE_TYPE (exp), arg0, arg1);
+
+	default:
+	  /* Strip sign ops from the argument of "odd" math functions.  */
+	  if (negate_mathfn_p (fcode))
+            {
+	      arg0 = fold_strip_sign_ops (TREE_VALUE (TREE_OPERAND (exp, 1)));
+	      if (arg0)
+		return build_function_call_expr (get_callee_fndecl (exp),
+						 build_tree_list (NULL_TREE,
+								  arg0));
+	    }
+	  break;
 	}
+      }
       break;

     default:
diff -rup orig/egcc-SVN20061112/gcc/testsuite/gcc.dg/builtins-20.c egcc-SVN20061112/gcc/testsuite/gcc.dg/builtins-20.c
--- orig/egcc-SVN20061112/gcc/testsuite/gcc.dg/builtins-20.c	2006-11-13 19:04:32.261549874 -0500
+++ egcc-SVN20061112/gcc/testsuite/gcc.dg/builtins-20.c	2006-11-13 19:27:54.352564065 -0500
@@ -16,18 +16,21 @@ extern double cos (double);
 extern double sin (double);
 extern double tan (double);
 extern double fabs (double);
+extern double copysign (double, 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 fabsf (float);
+extern float copysignf (float, 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 fabsl (long double);
+extern long double copysignl (long double, long double);
 extern long double hypotl (long double, long double);
 extern long double purel (long double) __attribute__ ((__pure__));

@@ -105,6 +108,12 @@ void test2(double x, double y)
   if (cos((y*=2, -fabs(tan(x/-y)))) != cos((y*=2,tan(x/y))))
     link_error ();

+  if (cos(copysign(x,y)) != cos(x))
+    link_error ();
+
+  if (cos(copysign(-fabs(x),y*=2)) != cos((y*=2,x)))
+    link_error ();
+
   if (hypot (x, 0) != fabs(x))
     link_error ();

@@ -222,6 +231,12 @@ void test2f(float x, float y)
   if (cosf((y*=2, -fabsf(tanf(x/-y)))) != cosf((y*=2,tanf(x/y))))
     link_error ();

+  if (cosf(copysignf(x,y)) != cosf(x))
+    link_error ();
+
+  if (cosf(copysignf(-fabsf(x),y*=2)) != cosf((y*=2,x)))
+    link_error ();
+
   if (hypotf (x, 0) != fabsf(x))
     link_error ();

@@ -340,6 +355,12 @@ void test2l(long double x, long double y
   if (cosl((y*=2, -fabsl(tanl(x/-y)))) != cosl((y*=2,tanl(x/y))))
     link_error ();

+  if (cosl(copysignl(x,y)) != cosl(x))
+    link_error ();
+
+  if (cosl(copysignl(-fabsl(x),y*=2)) != cosl((y*=2,x)))
+    link_error ();
+
   if (hypotl (x, 0) != fabsl(x))
     link_error ();


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