From: Richard Guenther Date: Mon, 24 Aug 2009 09:56:30 +0000 (+0000) Subject: re PR middle-end/41094 (Erroneous optimization of pow() with -ffast-math) X-Git-Tag: releases/gcc-4.3.5~415 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f5094d0c55ac4538e9a8f98b1f5f0858380e4bdb;p=thirdparty%2Fgcc.git re PR middle-end/41094 (Erroneous optimization of pow() with -ffast-math) 2009-08-24 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. From-SVN: r151052 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ee1b3f6a5923..9ececb23744e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-08-24 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-23 Uros Bizjak PR target/40718 diff --git a/gcc/builtins.c b/gcc/builtins.c index 82bc24f84ba3..1185b429d81e 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8459,15 +8459,18 @@ fold_builtin_pow (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 (MULT_EXPR, type, arg01, arg1); - return build_call_expr (fndecl, 2, arg00, narg1); + if (tree_expr_nonnegative_p (arg00)) + { + tree arg01 = CALL_EXPR_ARG (arg0, 1); + tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1); + return build_call_expr (fndecl, 2, arg00, narg1); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9b42c586580..cc883d55e9ee 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-08-24 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-23 Tobias Burnus PR fortran/40851 diff --git a/gcc/testsuite/gcc.dg/builtins-10.c b/gcc/testsuite/gcc.dg/builtins-10.c index d90e61ab3263..1b141fda2520 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 a63ebf554238..d1403c46c942 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 000000000000..2a4e9616cbfa --- /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; +}