changeset 13837:d7a891a411c1

strtod: work around icc bug With optimization, ICC 10.0 mis-compiles 'cond ? -val : val' such that a val of 0.0 doesn't result in -0.0. * lib/strtod.c (minus_zero): Define to working value. (strtod): Use it to avoid icc bug. Signed-off-by: Eric Blake <eblake@redhat.com>
author Eric Blake <eblake@redhat.com>
date Fri, 05 Nov 2010 08:30:27 -0600
parents 2ba13be8e841
children 2a545b8a8c9e
files ChangeLog lib/strtod.c
diffstat 2 files changed, 23 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2010-11-05  Eric Blake  <eblake@redhat.com>
 
+	strtod: work around icc bug
+	* lib/strtod.c (minus_zero): Define to working value.
+	(strtod): Use it to avoid icc bug.
+
 	copysign: enhance tests
 	* modules/copysign-tests (Files): Add minus-zero.h.
 	* tests/test-copysign.c (main): Also test zeros.
--- a/lib/strtod.c
+++ b/lib/strtod.c
@@ -190,6 +190,21 @@
 
 static double underlying_strtod (const char *, char **);
 
+/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
+   ICC 10.0 has a bug when optimizing the expression -zero.
+   The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
+   to PowerPC on MacOS X 10.5.  */
+#if defined __hpux || defined __sgi || defined __ICC
+static double
+compute_minus_zero (void)
+{
+  return -DBL_MIN * DBL_MIN;
+}
+# define minus_zero compute_minus_zero ()
+#else
+double minus_zero = -0.0;
+#endif
+
 /* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
    character after the last one used in the number is put in *ENDPTR.  */
 double
@@ -320,6 +335,10 @@
 
   if (endptr != NULL)
     *endptr = (char *) s;
+  /* Special case -0.0, since at least ICC miscompiles negation.  We
+     can't use copysign(), as that drags in -lm on some platforms.  */
+  if (!num && negative)
+    return minus_zero;
   return negative ? -num : num;
 }