fold-const.c (fold_strip_sign_ops): Handle copysign.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Sat, 18 Nov 2006 20:29:22 +0000 (20:29 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Sat, 18 Nov 2006 20:29:22 +0000 (20:29 +0000)
* fold-const.c (fold_strip_sign_ops): Handle copysign.

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

From-SVN: r118975

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtins-20.c

index e37276edb40fc25e69f06a8b973394a6e0c3f6bc..0df21ccca998753fba5e622911a15a796cd2f56b 100644 (file)
@@ -1,3 +1,7 @@
+2006-11-18  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * fold-const.c (fold_strip_sign_ops): Handle copysign.
+
 2006-11-18  Richard Guenther  <rguenther@suse.de>
 
        * config/i386/i386.c (ix86_builtins): New array for ix86
index 143dcadcfa4911e2f2bddd36757550fc5c77fb0d..cd7f1d9e831699b3c6a0479b0ba62f19c65dfd8d 100644 (file)
@@ -13388,14 +13388,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:
index 2eff1c87b7e77fcb482a09880735e0cfe1b7090e..c23dae9fb653644934f75f2dc7c7e3bea0cf973d 100644 (file)
@@ -1,3 +1,7 @@
+2006-11-18  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * gcc.dg/builtins-20.c: Add cases for copysign.
+
 2006-11-18  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
        PR fortran/24285
index ff9bf92dd01a770cdcb786341a81e339170e985d..bb90aec9672aa9256921aefb9ddfbafa24d7c0fa 100644 (file)
@@ -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 ();