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)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 01:07:40 +0000 (10:07 +0900)
        (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/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/builtin-cproj-1.c

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 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
index 31cd587..2454031 100644 (file)
@@ -44,80 +44,7 @@ extern void link_error(int);
     link_error(__LINE__); \
 } while (0)
 
-/* Test that cproj(X + I*INF) -> (ZERO + INF), where ZERO is +-0i.
-   NEG is either blank or a minus sign when ZERO is negative.  */
-#define TEST_IMAG_INF(NEG,ZERO) do { \
-  if (CPROJF(f+I*NEG INF) != ZERO+INF \
-      || CKSGN_I (CPROJF(f+I*NEG INF), ZERO+INF)) \
-    link_error(__LINE__); \
-  if (CPROJ(d+I*NEG INF) != ZERO+INF \
-      || CKSGN_I (CPROJ(d+I*NEG INF), ZERO+INF)) \
-    link_error(__LINE__); \
-  if (CPROJL(ld+I*NEG INF) != ZERO+INF \
-      || CKSGN_I (CPROJL(ld+I*NEG INF), ZERO+INF)) \
-    link_error(__LINE__); \
-} while (0)
-
-/* Like TEST_IMAG_INF, but check that side effects are honored.  */
-#define TEST_IMAG_INF_SIDE_EFFECT(NEG,ZERO) do { \
-  int side = 4; \
-  if (CPROJF(++side+I*NEG INF) != ZERO+INF \
-      || CKSGN_I (CPROJF(++side+I*NEG INF), ZERO+INF)) \
-    link_error(__LINE__); \
-  if (CPROJ(++side+I*NEG INF) != ZERO+INF \
-      || CKSGN_I (CPROJ(++side+I*NEG INF), ZERO+INF)) \
-    link_error(__LINE__); \
-  if (CPROJL(++side+I*NEG INF) != ZERO+INF \
-      || CKSGN_I (CPROJL(++side+I*NEG INF), ZERO+INF)) \
-    link_error(__LINE__); \
-  if (side != 10) \
-    link_error(__LINE__); \
-} while (0)
-
-/* Test that cproj(INF, POSITIVE) -> INF+0i.  NEG is either blank or a
-   minus sign to test negative INF.  */
-#define TEST_REAL_INF(NEG) do { \
-  __real cf = NEG INF; \
-  __imag cf = (x ? 4 : 5); \
-  if (CPROJF(cf) != INF \
-      || CKSGN_I (CPROJF(cf), INF)) \
-    link_error(__LINE__); \
-  __real cd = NEG INF; \
-  __imag cd = (x ? 4 : 5); \
-  if (CPROJ(cd) != INF \
-      || CKSGN_I (CPROJ(cd), INF)) \
-    link_error(__LINE__); \
-  __real cld = NEG INF; \
-  __imag cld = (x ? 4 : 5); \
-  if (CPROJL(cld) != INF \
-      || CKSGN_I (CPROJL(cld), INF)) \
-    link_error(__LINE__); \
-} while (0)
-
-/* Like TEST_REAL_INF, but check that side effects are honored.  */
-#define TEST_REAL_INF_SIDE_EFFECT(NEG) do { \
-  int side = -9; \
-  __real cf = NEG INF; \
-  __imag cf = (x ? 4 : 5); \
-  if (CPROJF((++side,cf)) != INF \
-      || CKSGN_I (CPROJF((++side,cf)), INF)) \
-    link_error(__LINE__); \
-  __real cd = NEG INF; \
-  __imag cd = (x ? 4 : 5); \
-  if (CPROJ((++side,cd)) != INF \
-      || CKSGN_I (CPROJ((++side,cd)), INF)) \
-    link_error(__LINE__); \
-  __real cld = NEG INF; \
-  __imag cld = (x ? 4 : 5); \
-  if (CPROJL((++side,cld)) != INF \
-      || CKSGN_I (CPROJL((++side,cld)), INF)) \
-    link_error(__LINE__); \
-  if (side != -3) \
-    link_error(__LINE__); \
-} while (0)
-
-void foo (_Complex long double cld, _Complex double cd, _Complex float cf,
-         long double ld, double d, float f, int x)
+void foo (void)
 {
   TEST_CST_INF (INF+0I, 0);
   TEST_CST_INF (INF-0I, -0.FI);
@@ -152,20 +79,6 @@ void foo (_Complex long double cld, _Complex double cd, _Complex float cf,
   TEST_CST (-22+3I);
   TEST_CST (-22-3I);
 
-  TEST_IMAG_INF (,0.FI);
-  TEST_IMAG_INF (-,-0.FI);
-
-#ifdef __OPTIMIZE__
-  TEST_REAL_INF( );
-  TEST_REAL_INF(-);
-  
-  TEST_IMAG_INF_SIDE_EFFECT (,0.FI);
-  TEST_IMAG_INF_SIDE_EFFECT (-,-0.FI);
-
-  TEST_REAL_INF_SIDE_EFFECT( );
-  TEST_REAL_INF_SIDE_EFFECT(-);
-#endif
-
   return;
 }