aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/fold-const.c29
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-20.c21
4 files changed, 51 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e37276e..0df21cc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 143dcad..cd7f1d9 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2eff1c8..c23dae9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/builtins-20.c b/gcc/testsuite/gcc.dg/builtins-20.c
index ff9bf92..bb90aec 100644
--- a/gcc/testsuite/gcc.dg/builtins-20.c
+++ b/gcc/testsuite/gcc.dg/builtins-20.c
@@ -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 ();