OSDN Git Service

* builtins.c (build_complex_cproj, fold_builtin_cproj): New.
authorghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 20:09:17 +0000 (20:09 +0000)
committerghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 20:09:17 +0000 (20:09 +0000)
        (fold_builtin_1): Fold builtin cproj.
        * builtins.def (BUILT_IN_CPROJ, BUILT_IN_CPROJF, BUILT_IN_CPROJL):
        Use ATTR_CONST_NOTHROW_LIST.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158573 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/builtins.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c [new file with mode: 0644]

index d4608ca..72c4c9a 100644 (file)
@@ -1,3 +1,10 @@
+2010-04-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * builtins.c (build_complex_cproj, fold_builtin_cproj): New.
+       (fold_builtin_1): Fold builtin cproj.
+       * builtins.def (BUILT_IN_CPROJ, BUILT_IN_CPROJF, BUILT_IN_CPROJL):
+       Use ATTR_CONST_NOTHROW_LIST.
+
 2010-04-20  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (ffs<mode>2): Macroize expander from ffs_cmove
index 65940dd..8c3c8e0 100644 (file)
@@ -7042,6 +7042,50 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
   return NULL_TREE;
 }
 
+/* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
+   complex tree type of the result.  If NEG is true, the imaginary
+   zero is negative.  */
+
+static tree
+build_complex_cproj (tree type, bool neg)
+{
+  REAL_VALUE_TYPE rinf, rzero = dconst0;
+  
+  real_inf (&rinf);
+  rzero.sign = neg;
+  return build_complex (type, build_real (TREE_TYPE (type), rinf),
+                       build_real (TREE_TYPE (type), rzero));
+}
+
+/* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is the
+   return type.  Return NULL_TREE if no simplification can be made.  */
+
+static tree
+fold_builtin_cproj (location_t loc, tree arg, tree type)
+{
+  if (!validate_arg (arg, COMPLEX_TYPE)
+      || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
+    return NULL_TREE;
+
+  /* If there are no infinities, return arg.  */
+  if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
+    return non_lvalue_loc (loc, arg);
+
+  /* Calculate the result when the argument is a constant.  */
+  if (TREE_CODE (arg) == COMPLEX_CST)
+    {
+      const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
+      const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
+      
+      if (real_isinf (real) || real_isinf (imag))
+       return build_complex_cproj (type, imag->sign);
+      else
+       return arg;
+    }
+
+  return NULL_TREE;
+}
+
 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
    Return NULL_TREE if no simplification can be made.  */
 
@@ -9799,6 +9843,9 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
     CASE_FLT_FN (BUILT_IN_CCOSH):
       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
 
+    CASE_FLT_FN (BUILT_IN_CPROJ):
+      return fold_builtin_cproj(loc, arg0, type);
+
     CASE_FLT_FN (BUILT_IN_CSIN):
       if (validate_arg (arg0, COMPLEX_TYPE)
          && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
index 09177a9..4e4eb3e 100644 (file)
@@ -479,9 +479,9 @@ DEF_C99_BUILTIN        (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLE
 DEF_C99_BUILTIN        (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
 DEF_C99_BUILTIN        (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN        (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN        (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN        (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
 DEF_C99_BUILTIN        (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
index 186c8ae..c208207 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-20  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
+
+       * gcc.dg/torture/builtin-cproj-1.c: New.
+       * gcc.dg/torture/builtin-cproj-2.c: New.
+
 2010-04-20  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/43800
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c b/gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c
new file mode 100644 (file)
index 0000000..2454031
--- /dev/null
@@ -0,0 +1,88 @@
+/* Copyright (C) 2010  Free Software Foundation.
+
+   Verify that folding of built-in cproj is correctly performed by the
+   compiler.
+
+   Origin: Kaveh R. Ghazi,  April 9, 2010.  */
+
+/* { dg-do link } */
+
+/* All references to link_error should go away at compile-time.  The
+   argument is the __LINE__ number.  It appears in the tree dump file
+   and aids in debugging should any of the tests fail.  */
+extern void link_error(int);
+
+#define CPROJ(X) __builtin_cproj(X)
+#define CPROJF(X) __builtin_cprojf(X)
+#define CPROJL(X) __builtin_cprojl(X)
+#define INF __builtin_inff()
+#define I 1i
+#define CPSGN(X,Y) __builtin_copysignf((X),(Y))
+#define CIMAG(X) __builtin_cimagf(X)
+#define CREAL(X) __builtin_crealf(X)
+
+/* Check that the signs of the real and/or imaginary parts of two
+   complex numbers match.  */
+#define CKSGN(X,Y) (CKSGN_R(X,Y) || CKSGN_I(X,Y))
+#define CKSGN_R(X,Y) (CPSGN(1,CREAL(X)) != CPSGN(1,CREAL(Y)))
+#define CKSGN_I(X,Y) (CPSGN(1,CIMAG(X)) != CPSGN(1,CIMAG(Y)))
+
+/* Test that (cproj(X) == ZERO+Inf) and that the signs of the
+   imaginary parts match.  ZERO is +/- 0i.  */
+#define TEST_CST_INF(X,ZERO) do { \
+  if (CPROJF(X) != ZERO+INF || CKSGN_I(CPROJF(X),ZERO+INF)) \
+    link_error(__LINE__); \
+  if (CPROJ(X) != ZERO+INF || CKSGN_I(CPROJ(X),ZERO+INF)) \
+    link_error(__LINE__); \
+  if (CPROJL(X) != ZERO+INF || CKSGN_I(CPROJL(X),ZERO+INF)) \
+    link_error(__LINE__); \
+} while (0)
+
+/* Test that (cproj(X) == X) for all finite (X).  */
+#define TEST_CST(X) do { \
+  if (CPROJF(X) != (X) || CKSGN(CPROJF(X),(X))) \
+    link_error(__LINE__); \
+} while (0)
+
+void foo (void)
+{
+  TEST_CST_INF (INF+0I, 0);
+  TEST_CST_INF (INF-0I, -0.FI);
+  TEST_CST_INF (INF+4I, 0);
+  TEST_CST_INF (INF-4I, -0.FI);
+  TEST_CST_INF (-INF+0I, 0);
+  TEST_CST_INF (-INF-0I, -0.FI);
+  TEST_CST_INF (-INF+4I, 0);
+  TEST_CST_INF (-INF-4I, -0.FI);
+
+  TEST_CST_INF (0+I*INF, 0);
+  TEST_CST_INF (0-I*INF, -0.FI);
+  TEST_CST_INF (23+I*INF, 0);
+  TEST_CST_INF (23-I*INF, -0.FI);
+  TEST_CST_INF (-0.F+I*INF, 0);
+  TEST_CST_INF (-0.F-I*INF, -0.FI);
+  TEST_CST_INF (-23+I*INF, 0);
+  TEST_CST_INF (-23-I*INF, -0.FI);
+
+  TEST_CST_INF (INF+I*INF, 0);
+  TEST_CST_INF (INF-I*INF, -0.FI);
+  TEST_CST_INF (-INF+I*INF, 0);
+  TEST_CST_INF (-INF-I*INF, -0.FI);
+  
+  TEST_CST (0);
+  TEST_CST (-0.F);
+  TEST_CST (0-0.FI);
+  TEST_CST (-0.F-0.FI);
+  
+  TEST_CST (22+3I);
+  TEST_CST (22-3I);
+  TEST_CST (-22+3I);
+  TEST_CST (-22-3I);
+
+  return;
+}
+
+int main (void)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c b/gcc/testsuite/gcc.dg/torture/builtin-cproj-2.c
new file mode 100644 (file)
index 0000000..3933165
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 2010  Free Software Foundation.
+
+   Verify that folding of built-in cproj is correctly performed by the
+   compiler.  With -ffinite-math-only all cproj calls should be
+   eliminated regardless of what the argument is, or what is known
+   about it.
+
+   Origin: Kaveh R. Ghazi,  April 9, 2010.  */
+
+/* { dg-do link } */
+/* { dg-options "-ffinite-math-only" } */
+
+/* All references to link_error should go away at compile-time.  The
+   argument is the __LINE__ number.  It appears in the tree dump file
+   and aids in debugging should any of the tests fail.  */
+extern void link_error(int);
+
+#define CPROJ(X) __builtin_cproj(X)
+#define CPROJF(X) __builtin_cprojf(X)
+#define CPROJL(X) __builtin_cprojl(X)
+
+/* Test that the supplied expressions eliminte the cproj call.  */
+#define TEST_EXPRS(LD_EXPR, D_EXPR, F_EXPR) do { \
+  if (CPROJF(F_EXPR) != (F_EXPR)) \
+    link_error (__LINE__); \
+  if (CPROJ(D_EXPR) != (D_EXPR)) \
+    link_error (__LINE__); \
+  if (CPROJL(LD_EXPR) != (LD_EXPR)) \
+    link_error (__LINE__); \
+} while (0)
+
+void foo (_Complex long double cld, _Complex double cd, _Complex float cf)
+{
+#ifdef __OPTIMIZE__
+  TEST_EXPRS (cld, cd, cf);
+  TEST_EXPRS (cld*2, cd*2, cf*2);
+  TEST_EXPRS (cld*cld, cd*cd, cf*cf);
+#endif
+
+  return;
+}
+
+int main (void)
+{
+  return 0;
+}