gcc replaces pow(x, 0.5) by sqrt(x). This is invalid when x is -0. Indeed, according to ISO C99 (N1256), F.9.4.4: pow(±0, y) returns +0 for y > 0 and not an odd integer. So, pow(-0.0, 0.5) should return +0. But sqrt(-0.0) should return -0 according to the IEEE 754 standard (and F.9.4.5 from ISO C99). Testcase: #include <stdio.h> #include <math.h> int main (void) { volatile double x = -0.0; printf ("sqrt(-0) = %g\n", sqrt (x)); printf ("pow(-0,0.5) = %g\n", pow (x, 0.5)); return 0; }
If I understand correctly, the bug appears with: r119248 | rguenth | 2006-11-27 12:38:42 +0100 (Mon, 27 Nov 2006) | 10 lines 2006-11-27 Richard Guenther <rguenther@suse.de> PR middle-end/25620 * builtins.c (expand_builtin_pow): Optimize non integer valued constant exponents using sqrt or cbrt if possible. Always fall back to expanding via optabs. * gcc.target/i386/pow-1.c: New testcase. * gcc.dg/builtins-58.c: Likewise.
Mine.
While you are looking at this part, you may have to check that a similar problem does not exist when converting x*sqrt(x) to pow(w,1.5) and so on.
I checked, and these and similar transformations are always guarded by flag_unsafe_math_optimizations, so we should be fine, unless I missed a case of course. If you notice one, please create a bug report.
Looks like we need to guard this with HONOR_SIGNED_ZEROS.
Subject: Bug 43419 Author: matz Date: Thu Mar 18 16:07:53 2010 New Revision: 157543 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157543 Log: PR middle-end/43419 * builtins.c (expand_builtin_pow): Don't transform pow(x, 0.5) into sqrt(x) if we need to preserve signed zeros. testsuite/ * gcc.dg/pr43419.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/pr43419.c Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c trunk/gcc/testsuite/ChangeLog
Fixed.
Subject: Bug 43419 Author: jakub Date: Mon Mar 22 14:58:00 2010 New Revision: 157631 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=157631 Log: Backport from mainline: 2010-03-18 Michael Matz <matz@suse.de> PR middle-end/43419 * builtins.c (expand_builtin_pow): Don't transform pow(x, 0.5) into sqrt(x) if we need to preserve signed zeros. * gcc.dg/pr43419.c: New testcase. Added: branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/pr43419.c Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/builtins.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
This bug also affects 4.3 branch. The upstream patch applies Ok and fixes it.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.