[PATCH] fold copysign(x, REAL_CST)

Andrew Pinski apinski@apple.com
Fri Aug 20 19:53:00 GMT 2004


I saw that we were not folding copysign(x,10) for some reason so I 
decided
to implement it.  I also some dead code (after a return statement) in 
the
function which has been there since the function was added.

OK? Bootstrapped on powerpc-apple-darwin with no regressions.

ChangeLog:

	* builtins.c (fold_builtin_copysign): Remove dead code.
	Fold copysign (x, REAL_CST) into ABS (x) if the real is positive,
	otherwise -ABS (x) if we are not in gimple form.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.372
diff -u -p -r1.372 builtins.c
--- builtins.c	15 Aug 2004 15:44:49 -0000	1.372
+++ builtins.c	20 Aug 2004 18:36:23 -0000
@@ -7546,7 +7546,6 @@ fold_builtin_copysign (tree arglist, tre
        c2 = TREE_REAL_CST (arg2);
        real_copysign (&c1, &c2);
        return build_real (type, c1);
-      c1.sign = c2.sign;
      }

    /* copysign(X, Y) is fabs(X) when Y is always non-negative.
@@ -7556,6 +7555,22 @@ fold_builtin_copysign (tree arglist, tre
  			     fold (build1 (ABS_EXPR, type, arg1)),
  			     arg2);

+  /* If ARG2 is compile-time constant, we don't have to call the 
funciton. */
+  if (TREE_CODE (arg2) == REAL_CST && !TREE_CONSTANT_OVERFLOW (arg2))
+    {
+      tree temp = fold (build1 (ABS_EXPR, type, arg1));
+
+      if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg2)))
+        {
+	  if (in_gimple_form)
+	    return NULL_TREE;
+	
+	  temp = fold (build1 (NEGATE_EXPR, type, temp));
+	}
+
+      return temp;
+    }
+
    return NULL_TREE;
  }



Testcase (This was going to be gcc.dg/builtins-42.c but it looks Roger
committed the same testcase twice, from
<http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00289.html> plus one extra
test):

/* Copyright (C) 2004 Free Software Foundation.

    Check that constant folding of copysign, copysignf and copysignl math
    functions doesn't break anything and produces the expected results.

    Written by Roger Sayle, 6th June 2004.
    And add another test by Andrew Pinski, August 20, 2004.  */

/* { dg-do link } */
/* { dg-options "-O2 -ffast-math" } */

extern void link_error(void);

extern double fabs(double);
extern float fabsf(float);

extern double copysign(double, double);
extern float copysignf(float, float);


void test1(double x)
{
   if (copysign(x,x) != x)
     link_error ();
}

void test1f(float x)
{
   if (copysignf(x,x) != x)
     link_error ();
}


void test2(double x)
{
   if (copysign(x, 1.0) != fabs(x))
     link_error ();
}

void test2f(float x)
{
   if (copysign(x, 1.0f) != fabsf(x))
     link_error ();
}

void test3(double x)
{
   if (copysign(x, -1.0) != -fabs(x))
     link_error ();
}

void test3f(float x)
{
   if (copysign(x, -1.0f) != -fabsf(x))
     link_error ();
}


int main()
{
   test1(1.0);
   test2(1.0);
   test3(1.0);

   test1f(1.0f);
   test2f(1.0f);
   test3f(1.0f);

   return 0;
}



More information about the Gcc-patches mailing list