diff options
author | Richard Guenther <rguenth@gcc.gnu.org> | 2005-02-10 15:16:51 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2005-02-10 15:16:51 +0000 |
commit | ba78d4526f495d25a2d23025a4d782bfe73b591b (patch) | |
tree | 5744c490757838cc1805f58f3651b6c7d2e97ee2 | |
parent | 537f4eb35d1fa192c85ea5dc8335ecabc0024bae (diff) | |
download | gcc-ba78d4526f495d25a2d23025a4d782bfe73b591b.zip gcc-ba78d4526f495d25a2d23025a4d782bfe73b591b.tar.gz gcc-ba78d4526f495d25a2d23025a4d782bfe73b591b.tar.bz2 |
builtins.c (fold_builtin_powi): New function.
2005-02-10 Richard Guenther <rguenth@gcc.gnu.org>
* builtins.c (fold_builtin_powi): New function.
(fold_builtin_1): Call it.
* gcc.dg/builtins-52.c: New testcase.
From-SVN: r94831
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/builtins.c | 53 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtins-52.c | 23 |
4 files changed, 85 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e2c251a..199bd29 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2005-02-10 Richard Guenther <rguenth@gcc.gnu.org> + + * builtins.c (fold_builtin_powi): New function. + (fold_builtin_1): Call it. + 2005-02-10 Steven Bosscher <stevenb@suse.de> PR documentation/19309 diff --git a/gcc/builtins.c b/gcc/builtins.c index 432ecc6..a206240 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -152,6 +152,7 @@ static tree fold_builtin_cabs (tree, tree); static tree fold_builtin_sqrt (tree, tree); static tree fold_builtin_cbrt (tree, tree); static tree fold_builtin_pow (tree, tree, tree); +static tree fold_builtin_powi (tree, tree, tree); static tree fold_builtin_sin (tree); static tree fold_builtin_cos (tree, tree, tree); static tree fold_builtin_tan (tree); @@ -6948,6 +6949,53 @@ fold_builtin_pow (tree fndecl, tree arglist, tree type) return NULL_TREE; } +/* Fold a builtin function call to powi, powif, or powil. Return + NULL_TREE if no simplification can be made. */ +static tree +fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type) +{ + tree arg0 = TREE_VALUE (arglist); + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist)); + + if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE)) + return NULL_TREE; + + /* Optimize pow(1.0,y) = 1.0. */ + if (real_onep (arg0)) + return omit_one_operand (type, build_real (type, dconst1), arg1); + + if (host_integerp (arg1, 0)) + { + HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1); + + /* Evaluate powi at compile-time. */ + if (TREE_CODE (arg0) == REAL_CST + && ! TREE_CONSTANT_OVERFLOW (arg0)) + { + REAL_VALUE_TYPE x; + x = TREE_REAL_CST (arg0); + real_powi (&x, TYPE_MODE (type), &x, c); + return build_real (type, x); + } + + /* Optimize pow(x,0) = 1.0. */ + if (c == 0) + return omit_one_operand (type, build_real (type, dconst1), + arg0); + + /* Optimize pow(x,1) = x. */ + if (c == 1) + return arg0; + + /* Optimize pow(x,-1) = 1.0/x. */ + if (c == -1) + return fold (build2 (RDIV_EXPR, type, + build_real (type, dconst1), arg0)); + } + + return NULL_TREE; +} + /* A subroutine of fold_builtin to fold the various exponent functions. EXP is the CALL_EXPR of a call to a builtin function. VALUE is the value which will be raised to a power. */ @@ -7969,6 +8017,11 @@ fold_builtin_1 (tree exp, bool ignore) case BUILT_IN_POWL: return fold_builtin_pow (fndecl, arglist, type); + case BUILT_IN_POWI: + case BUILT_IN_POWIF: + case BUILT_IN_POWIL: + return fold_builtin_powi (fndecl, arglist, type); + case BUILT_IN_INF: case BUILT_IN_INFF: case BUILT_IN_INFL: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b73d947..6e7dc97 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-02-10 Richard Guenther <rguenth@gcc.gnu.org> + + * gcc.dg/builtins-52.c: New testcase. + 2005-02-10 Jakub Jelinek <jakub@redhat.com> PR c/19342 diff --git a/gcc/testsuite/gcc.dg/builtins-52.c b/gcc/testsuite/gcc.dg/builtins-52.c new file mode 100644 index 0000000..684fd66 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtins-52.c @@ -0,0 +1,23 @@ +/* { dg-do link } */ +/* { dg-options "-ffast-math" } */ + +extern void link_error(void); + +void test(double x, int n) +{ + if (__builtin_powi(x,-1.0) != 1.0/x) + link_error (); + if (__builtin_powi(x,0.0) != 1.0) + link_error (); + if (__builtin_powi(x,1.0) != x) + link_error (); + if (__builtin_powi(1.0,n) != 1.0) + link_error (); +} + +int main() +{ + test(7.3, 2); + return 0; +} + |