From 49e436b506b7817a4ef645c95ba158e88deda840 Mon Sep 17 00:00:00 2001 From: rguenth Date: Tue, 18 Aug 2009 13:40:18 +0000 Subject: [PATCH] 2009-08-18 Richard Guenther PR middle-end/41094 * builtins.c (fold_builtin_pow): Fold pow(pow(x,y),z) to pow(x,y*z) only if x is nonnegative. * gcc.dg/torture/pr41094.c: New testcase. * gcc.dg/torture/builtin-power-1.c: Adjust. * gcc.dg/builtins-10.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150874 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/builtins.c | 11 +++++++---- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/gcc.dg/builtins-10.c | 4 ++-- gcc/testsuite/gcc.dg/torture/builtin-power-1.c | 6 +++--- gcc/testsuite/gcc.dg/torture/pr41094.c | 19 +++++++++++++++++++ 6 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr41094.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index adbf70fe8bf..764d4d10870 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-08-18 Richard Guenther + + PR middle-end/41094 + * builtins.c (fold_builtin_pow): Fold pow(pow(x,y),z) to + pow(x,y*z) only if x is nonnegative. + 2009-08-18 Jakub Jelinek * bb-reorder.c (fix_up_fall_thru_edges): Only call invert_jump diff --git a/gcc/builtins.c b/gcc/builtins.c index 025c1694e4c..1a9e96653df 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8737,15 +8737,18 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type) } } - /* Optimize pow(pow(x,y),z) = pow(x,y*z). */ + /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */ if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF || fcode == BUILT_IN_POWL) { tree arg00 = CALL_EXPR_ARG (arg0, 0); - tree arg01 = CALL_EXPR_ARG (arg0, 1); - tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1); - return build_call_expr_loc (loc, fndecl, 2, arg00, narg1); + if (tree_expr_nonnegative_p (arg00)) + { + tree arg01 = CALL_EXPR_ARG (arg0, 1); + tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1); + return build_call_expr_loc (loc, fndecl, 2, arg00, narg1); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e1c0885d6af..464e14c2773 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-08-18 Richard Guenther + + PR middle-end/41094 + * gcc.dg/torture/pr41094.c: New testcase. + * gcc.dg/torture/builtin-power-1.c: Adjust. + * gcc.dg/builtins-10.c: Likewise. + 2009-08-18 Jakub Jelinek PR target/40971 diff --git a/gcc/testsuite/gcc.dg/builtins-10.c b/gcc/testsuite/gcc.dg/builtins-10.c index d90e61ab326..1b141fda252 100644 --- a/gcc/testsuite/gcc.dg/builtins-10.c +++ b/gcc/testsuite/gcc.dg/builtins-10.c @@ -25,7 +25,7 @@ void test(double x) link_error (); if (pow(pow(x,4.0),0.25) != x) - link_error (); + /* XFAIL. PR41098. */; } void test2(double x, double y, double z) @@ -42,7 +42,7 @@ void test2(double x, double y, double z) if (pow(sqrt(x),y) != pow(x,y*0.5)) link_error (); - if (pow(pow(x,y),z) != pow(x,y*z)) + if (pow(pow(fabs(x),y),z) != pow(fabs(x),y*z)) link_error (); } diff --git a/gcc/testsuite/gcc.dg/torture/builtin-power-1.c b/gcc/testsuite/gcc.dg/torture/builtin-power-1.c index a63ebf55423..d1403c46c94 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-power-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-power-1.c @@ -77,9 +77,9 @@ void test(double d1, double d2, double d3, /* Test pow(pow(x,y),z) -> pow(x,y*z). */ #define POW_POW \ extern void link_failure_pow_pow(void); \ - if (pow(pow(d1, d2), d3) != pow(d1,d2*d3) \ - || powf(powf(f1,f2),f3) != powf(f1,f2*f3) \ - || powl(powl(ld1,ld2),ld3) != powl(ld1,ld2*ld3)) \ + if (pow(pow(fabs(d1), d2), d3) != pow(fabs(d1),d2*d3) \ + || powf(powf(fabs(f1),f2),f3) != powf(fabs(f1),f2*f3) \ + || powl(powl(fabs(ld1),ld2),ld3) != powl(fabs(ld1),ld2*ld3)) \ link_failure_pow_pow() POW_POW; diff --git a/gcc/testsuite/gcc.dg/torture/pr41094.c b/gcc/testsuite/gcc.dg/torture/pr41094.c new file mode 100644 index 00000000000..2a4e9616cbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr41094.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-ffast-math" } */ + +#include + +extern void abort (void); + +double foo(void) +{ + double x = -4.0; + return pow (x * x, 0.25); +} + +int main() +{ + if (foo() != 2.0) + abort (); + return 0; +} -- 2.11.0