diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-01-23 16:16:33 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-01-23 16:16:33 +0000 |
commit | 25348c94e7a966a65fe94f62563ad1982f2f9923 (patch) | |
tree | a4e7871be466032d2019d3dd74d2f1702b848756 /gcc/builtins.c | |
parent | 69f2de23b2401a6602271262a103270a81d5f175 (diff) | |
download | gcc-25348c94e7a966a65fe94f62563ad1982f2f9923.tar.gz |
real.c (real_floor, real_ceil): Tweak to allow input and output arguments to overlap.
* real.c (real_floor, real_ceil): Tweak to allow input and output
arguments to overlap.
(real_round): New function to implement round(3m) semantics.
* real.h (real_round): Prototype here.
* builtins.c (fold_builtin_round): New function to constant fold
round, roundf and roundl.
(fold_builtin): Call fold_builtin_round for BUILT_IN_ROUND{,F,L}.
* gcc.dg/builtins-29.c: New test case.
From-SVN: r76428
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 3174e75cea2..2dfc0e8a89e 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -156,6 +156,7 @@ static tree fold_builtin_cabs (tree, tree, tree); static tree fold_builtin_trunc (tree); static tree fold_builtin_floor (tree); static tree fold_builtin_ceil (tree); +static tree fold_builtin_round (tree); static tree fold_builtin_bitop (tree); static tree fold_builtin_memcpy (tree); static tree fold_builtin_mempcpy (tree); @@ -5923,6 +5924,38 @@ fold_builtin_ceil (tree exp) return fold_trunc_transparent_mathfn (exp); } +/* Fold function call to builtin round, roundf or roundl. Return + NULL_TREE if no simplification can be made. */ + +static tree +fold_builtin_round (tree exp) +{ + tree arglist = TREE_OPERAND (exp, 1); + tree arg; + + if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) + return 0; + + /* Optimize ceil of constant value. */ + arg = TREE_VALUE (arglist); + if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg)) + { + REAL_VALUE_TYPE x; + + x = TREE_REAL_CST (arg); + if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math) + { + tree type = TREE_TYPE (exp); + REAL_VALUE_TYPE r; + + real_round (&r, TYPE_MODE (type), &x); + return build_real (type, r); + } + } + + return fold_trunc_transparent_mathfn (exp); +} + /* Fold function call to builtin ffs, clz, ctz, popcount and parity and their long and long long variants (i.e. ffsl and ffsll). Return NULL_TREE if no simplification can be made. */ @@ -6868,6 +6901,8 @@ fold_builtin (tree exp) case BUILT_IN_ROUND: case BUILT_IN_ROUNDF: case BUILT_IN_ROUNDL: + return fold_builtin_round (exp); + case BUILT_IN_NEARBYINT: case BUILT_IN_NEARBYINTF: case BUILT_IN_NEARBYINTL: |