aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2010-04-20 20:09:17 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2010-04-20 20:09:17 +0000
commit43272bf5fd3d66bf2fd05d11cf66dc0d1116a701 (patch)
tree69005f1c685a98a731edd08d1cb85b99b722570f /gcc/builtins.c
parent5a80a1ddff8f6a6c5b7395a258361f8d46106657 (diff)
downloadgcc-43272bf5fd3d66bf2fd05d11cf66dc0d1116a701.zip
gcc-43272bf5fd3d66bf2fd05d11cf66dc0d1116a701.tar.gz
gcc-43272bf5fd3d66bf2fd05d11cf66dc0d1116a701.tar.bz2
builtins.c (build_complex_cproj, [...]): New.
* 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. From-SVN: r158573
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 65940dd..8c3c8e0 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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)