diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-06-07 20:50:14 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-06-07 20:50:14 +0000 |
commit | 67057c537b7f1f895ff87f8616e8a122f886f1bf (patch) | |
tree | cf683ee1008a7ca53b18dd77effb242f594c9a57 /gcc/builtins.c | |
parent | f29b9db93eb2f3508d2376103af158675f1ee2b0 (diff) | |
download | gcc-67057c537b7f1f895ff87f8616e8a122f886f1bf.zip gcc-67057c537b7f1f895ff87f8616e8a122f886f1bf.tar.gz gcc-67057c537b7f1f895ff87f8616e8a122f886f1bf.tar.bz2 |
real.c (real_copysign): New function to implement libm's copysign.
* real.c (real_copysign): New function to implement libm's copysign.
* real.h (real_copysign): Prototype here.
* fold-const.c (tree_expr_nonnegative_p): The result of sqrt, sqrtf
and sqrtl can be negative, as sqrt(-0.0) = -0.0. Correct whitespace.
* builtins.c (fold_builtin_isascii, fold_builtin_toascii,
fold_builtin_isdigit): Add function prototypes.
(fold_builtin_copysign): New function to fold copysign, copysignf
and copysignl. Optimize copysign(x,x) as x. Evaluate copysign of
constant arguments at compile-time using real_copysign. Fold
copysign(X,Y) as fabs(X) if Y is always non-negative.
(fold_builtin_1): Correct minor whitespace/style issues. Call
fold_builtin_copysign for BUILT_IN_COPYSIGN{,F,L}.
* gcc.dg/builtins-41.c: New test case.
* gcc.dg/builtins-42.c: New test case.
From-SVN: r82721
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index e265186..d10924f 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -162,6 +162,10 @@ static tree fold_builtin_memcmp (tree); static tree fold_builtin_strcmp (tree); static tree fold_builtin_strncmp (tree); static tree fold_builtin_signbit (tree); +static tree fold_builtin_copysign (tree, tree); +static tree fold_builtin_isascii (tree); +static tree fold_builtin_toascii (tree); +static tree fold_builtin_isdigit (tree); static tree simplify_builtin_memcmp (tree); static tree simplify_builtin_strcmp (tree); @@ -7298,6 +7302,49 @@ fold_builtin_signbit (tree exp) return NULL_TREE; } +/* Fold function call to builtin copysign, copysignf or copysignl. + Return NULL_TREE if no simplification can be made. */ + +static tree +fold_builtin_copysign (tree arglist, tree type) +{ + tree arg1, arg2; + + if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) + return NULL_TREE; + + arg1 = TREE_VALUE (arglist); + arg2 = TREE_VALUE (TREE_CHAIN (arglist)); + + /* copysign(X,X) is X. */ + if (operand_equal_p (arg1, arg2, 0)) + return fold_convert (type, arg1); + + /* If ARG1 and ARG2 are compile-time constants, determine the result. */ + if (TREE_CODE (arg1) == REAL_CST + && TREE_CODE (arg2) == REAL_CST + && !TREE_CONSTANT_OVERFLOW (arg1) + && !TREE_CONSTANT_OVERFLOW (arg2)) + { + REAL_VALUE_TYPE c1, c2; + + c1 = TREE_REAL_CST (arg1); + c2 = TREE_REAL_CST (arg2); + real_copysign (&c1, &c2); + return build_real (type, c1); + c1.sign = c2.sign; + } + + /* copysign(X, Y) is fabs(X) when Y is always non-negative. + Remember to evaluate Y for side-effects. */ + if (tree_expr_nonnegative_p (arg2)) + return omit_one_operand (type, + fold (build1 (ABS_EXPR, type, arg1)), + arg2); + + return NULL_TREE; +} + /* Fold a call to builtin isascii. */ static tree @@ -7577,10 +7624,12 @@ fold_builtin_1 (tree exp) case BUILT_IN_EXPF: case BUILT_IN_EXPL: return fold_builtin_exponent (exp, &dconste); + case BUILT_IN_EXP2: case BUILT_IN_EXP2F: case BUILT_IN_EXP2L: return fold_builtin_exponent (exp, &dconst2); + case BUILT_IN_EXP10: case BUILT_IN_EXP10F: case BUILT_IN_EXP10L: @@ -7588,21 +7637,21 @@ fold_builtin_1 (tree exp) case BUILT_IN_POW10F: case BUILT_IN_POW10L: return fold_builtin_exponent (exp, &dconst10); + case BUILT_IN_LOG: case BUILT_IN_LOGF: case BUILT_IN_LOGL: return fold_builtin_logarithm (exp, &dconste); - break; + case BUILT_IN_LOG2: case BUILT_IN_LOG2F: case BUILT_IN_LOG2L: return fold_builtin_logarithm (exp, &dconst2); - break; + case BUILT_IN_LOG10: case BUILT_IN_LOG10F: case BUILT_IN_LOG10L: return fold_builtin_logarithm (exp, &dconst10); - break; case BUILT_IN_TAN: case BUILT_IN_TANF: @@ -7884,6 +7933,11 @@ fold_builtin_1 (tree exp) case BUILT_IN_ISDIGIT: return fold_builtin_isdigit (arglist); + case BUILT_IN_COPYSIGN: + case BUILT_IN_COPYSIGNF: + case BUILT_IN_COPYSIGNL: + return fold_builtin_copysign (arglist, type); + default: break; } |