diff options
author | Kaveh R. Ghazi <ghazi@caip.rutgers.edu> | 2010-04-20 20:09:17 +0000 |
---|---|---|
committer | Kaveh Ghazi <ghazi@gcc.gnu.org> | 2010-04-20 20:09:17 +0000 |
commit | 43272bf5fd3d66bf2fd05d11cf66dc0d1116a701 (patch) | |
tree | 69005f1c685a98a731edd08d1cb85b99b722570f /gcc/builtins.c | |
parent | 5a80a1ddff8f6a6c5b7395a258361f8d46106657 (diff) | |
download | gcc-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.c | 47 |
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) |