]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Work around powerpc32 integer 0 converting to -0 (bug 887, bug 19049, bug 19050).
authorJoseph Myers <joseph@codesourcery.com>
Mon, 5 Oct 2015 17:46:50 +0000 (17:46 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Mon, 5 Oct 2015 17:46:50 +0000 (17:46 +0000)
On powerpc32 hard-float, older processors (ones where fcfid is not
available for 32-bit code), GCC generates conversions from integers to
floating point that wrongly convert integer 0 to -0 instead of +0 in
FE_DOWNWARD mode.  This in turn results in logb and a few other
functions wrongly returning -0 when they should return +0.

This patch works around this issue in glibc as I proposed in
<https://sourceware.org/ml/libc-alpha/2015-09/msg00728.html>, so that
the affected functions can be correct and the affected tests pass in
the absence of a GCC fix for this longstanding issue (GCC bug 67771 -
if fixed, of course we can put in GCC version conditionals, and
eventually phase out the workarounds).  A new macro
FIX_INT_FP_CONVERT_ZERO is added in a new sysdeps header
fix-int-fp-convert-zero.h, and the powerpc32/fpu version of that
header defines the macro based on the results of a configure test for
whether such conversions use the fcfid instruction.

Tested for x86_64 (that installed stripped shared libraries are
unchanged by the patch) and powerpc (that HAVE_PPC_FCFID comes out to
0 as expected and that the relevant tests are fixed).  Also tested a
build with GCC configured for -mcpu=power4 and verified that
HAVE_PPC_FCFID comes out to 1 in that case.

There are still some other issues to fix to get test-float and
test-double passing cleanly for older powerpc32 processors (apart from
the need for an ulps regeneration for powerpc).  (test-ldouble will be
harder to get passing cleanly, but with a combination of selected
fixes to ldbl-128ibm code that don't involve significant performance
issues, allowing spurious underflow and inexact exceptions for that
format, and lots of XFAILing for the default case of unpatched libgcc,
it should be doable.)

[BZ #887]
[BZ #19049]
[BZ #19050]
* sysdeps/generic/fix-int-fp-convert-zero.h: New file.
* sysdeps/ieee754/dbl-64/e_log10.c: Include
<fix-int-fp-convert-zero.h>.
(__ieee754_log10): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/dbl-64/e_log2.c: Include
<fix-int-fp-convert-zero.h>.
(__ieee754_log2): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/dbl-64/s_erf.c: Include
<fix-int-fp-convert-zero.h>.
(__erfc): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/dbl-64/s_logb.c: Include
<fix-int-fp-convert-zero.h>.
(__logb): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/flt-32/e_log10f.c: Include
<fix-int-fp-convert-zero.h>.
(__ieee754_log10f): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/flt-32/e_log2f.c: Include
<fix-int-fp-convert-zero.h>.
(__ieee754_log2f): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/flt-32/s_erff.c: Include
<fix-int-fp-convert-zero.h>.
(__erfcf): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/flt-32/s_logbf.c: Include
<fix-int-fp-convert-zero.h>.
(__logbf): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/ldbl-128ibm/s_erfl.c: Include
<fix-int-fp-convert-zero.h>.
(__erfcl): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/ieee754/ldbl-128ibm/s_logbl.c: Include
<fix-int-fp-convert-zero.h>.
(__logbl): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
* sysdeps/powerpc/powerpc32/fpu/configure.ac: New file.
* sysdeps/powerpc/powerpc32/fpu/configure: New generated file.
* sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h: New
file.
* config.h.in [_LIBC] (HAVE_PPC_FCFID): New macro.

17 files changed:
ChangeLog
NEWS
config.h.in
sysdeps/generic/fix-int-fp-convert-zero.h [new file with mode: 0644]
sysdeps/ieee754/dbl-64/e_log10.c
sysdeps/ieee754/dbl-64/e_log2.c
sysdeps/ieee754/dbl-64/s_erf.c
sysdeps/ieee754/dbl-64/s_logb.c
sysdeps/ieee754/flt-32/e_log10f.c
sysdeps/ieee754/flt-32/e_log2f.c
sysdeps/ieee754/flt-32/s_erff.c
sysdeps/ieee754/flt-32/s_logbf.c
sysdeps/ieee754/ldbl-128ibm/s_erfl.c
sysdeps/ieee754/ldbl-128ibm/s_logbl.c
sysdeps/powerpc/powerpc32/fpu/configure [new file with mode: 0644]
sysdeps/powerpc/powerpc32/fpu/configure.ac [new file with mode: 0644]
sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h [new file with mode: 0644]

index 0bfe2bbde9c6df4d428e98f26ed3305e2fa43c2e..a86b74f95074652904f2056e29e51136f4245070 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2015-10-05  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #887]
+       [BZ #19049]
+       [BZ #19050]
+       * sysdeps/generic/fix-int-fp-convert-zero.h: New file.
+       * sysdeps/ieee754/dbl-64/e_log10.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__ieee754_log10): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/dbl-64/e_log2.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__ieee754_log2): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/dbl-64/s_erf.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__erfc): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/dbl-64/s_logb.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__logb): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/flt-32/e_log10f.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__ieee754_log10f): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/flt-32/e_log2f.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__ieee754_log2f): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/flt-32/s_erff.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__erfcf): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/flt-32/s_logbf.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__logbf): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/ldbl-128ibm/s_erfl.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__erfcl): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/ieee754/ldbl-128ibm/s_logbl.c: Include
+       <fix-int-fp-convert-zero.h>.
+       (__logbl): Adjust signs as needed if FIX_INT_FP_CONVERT_ZERO.
+       * sysdeps/powerpc/powerpc32/fpu/configure.ac: New file.
+       * sysdeps/powerpc/powerpc32/fpu/configure: New generated file.
+       * sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h: New
+       file.
+       * config.h.in [_LIBC] (HAVE_PPC_FCFID): New macro.
+
 2015-10-03  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
        * sysdeps/x86_64/fpu/libm-test-ulps: Regenerated.
diff --git a/NEWS b/NEWS
index 05d962221bd2b49e6a5214f918c28c8dccd57424..832451353c208ef943fd256a5a7a2bb2b4942dff 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,15 +9,15 @@ Version 2.23
 
 * The following bugs are resolved with this release:
 
-  2542, 2543, 2558, 2898, 4404, 6803, 14341, 14912, 15367, 15384, 15786,
-  15918, 16141, 16296, 16347, 16415, 16517, 16519, 16520, 16521, 16620,
-  16734, 16973, 16985, 17118, 17243, 17244, 17250, 17441, 17787, 17886,
-  17887, 17905, 18084, 18086, 18240, 18265, 18370, 18421, 18480, 18525,
-  18595, 18610, 18618, 18647, 18661, 18674, 18675, 18681, 18724, 18757,
-  18778, 18781, 18787, 18789, 18790, 18795, 18796, 18803, 18820, 18823,
-  18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875, 18887, 18921,
-  18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970, 18977, 18980,
-  18981, 18985, 19003, 19016, 19032, 19046, 19059.
+  887, 2542, 2543, 2558, 2898, 4404, 6803, 14341, 14912, 15367, 15384,
+  15786, 15918, 16141, 16296, 16347, 16415, 16517, 16519, 16520, 16521,
+  16620, 16734, 16973, 16985, 17118, 17243, 17244, 17250, 17441, 17787,
+  17886, 17887, 17905, 18084, 18086, 18240, 18265, 18370, 18421, 18480,
+  18525, 18595, 18610, 18618, 18647, 18661, 18674, 18675, 18681, 18724,
+  18757, 18778, 18781, 18787, 18789, 18790, 18795, 18796, 18803, 18820,
+  18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875, 18887,
+  18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970, 18977,
+  18980, 18981, 18985, 19003, 19016, 19032, 19046, 19049, 19050, 19059.
 
 * The obsolete header <regexp.h> has been removed.  Programs that require
   this header must be updated to use <regex.h> instead.
index 8d44b8a7a98878701e919bf37f66a64ef3e85e8f..865eaf3855190295150c6758a919a9de15873a01 100644 (file)
 /* The PowerPC64 ELFv2 ABI is being used.  */
 #undef HAVE_ELFV2_ABI
 
+/* PowerPC32 uses fcfid for integer to floating point conversions.  */
+#define HAVE_PPC_FCFID 0
+
 #endif
diff --git a/sysdeps/generic/fix-int-fp-convert-zero.h b/sysdeps/generic/fix-int-fp-convert-zero.h
new file mode 100644 (file)
index 0000000..b7fd38e
--- /dev/null
@@ -0,0 +1,27 @@
+/* Fix for conversion of integer 0 to floating point.  Generic version.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef FIX_INT_FP_CONVERT_ZERO_H
+#define FIX_INT_FP_CONVERT_ZERO_H      1
+
+/* Define this macro to 1 to work around conversions of integer 0 to
+   floating point returning -0 instead of the correct +0 in some
+   rounding modes.  */
+#define FIX_INT_FP_CONVERT_ZERO 0
+
+#endif /* fix-int-fp-convert-zero.h */
index 8548ee39428d1a2a24871bc56fb6b139e6d226a8..df59d9dce47ea9b3bdf4d7b73eaf9aeb79863944 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 static const double two54 = 1.80143985094819840000e+16;         /* 0x43500000, 0x00000000 */
 static const double ivln10 = 4.34294481903251816668e-01;        /* 0x3FDBCB7B, 0x1526E50E */
@@ -77,6 +78,8 @@ __ieee754_log10 (double x)
   i = ((u_int32_t) k & 0x80000000) >> 31;
   hx = (hx & 0x000fffff) | ((0x3ff - i) << 20);
   y = (double) (k + i);
+  if (FIX_INT_FP_CONVERT_ZERO && y == 0.0)
+    y = 0.0;
   SET_HIGH_WORD (x, hx);
   z = y * log10_2lo + ivln10 * __ieee754_log (x);
   return z + y * log10_2hi;
index 997d7cefc81ed79784dd4f00dfc38b39c9d91a00..bc6a34192acb8202dbb36df943713da50ddc3f1f 100644 (file)
@@ -56,6 +56,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 static const double ln2 = 0.69314718055994530942;
 static const double two54 = 1.80143985094819840000e+16; /* 43500000 00000000 */
@@ -101,7 +102,11 @@ __ieee754_log2 (double x)
   if ((0x000fffff & (2 + hx)) < 3)
     {                           /* |f| < 2**-20 */
       if (f == zero)
-       return dk;
+       {
+         if (FIX_INT_FP_CONVERT_ZERO && dk == 0.0)
+           dk = 0.0;
+         return dk;
+       }
       R = f * f * (0.5 - 0.33333333333333333 * f);
       return dk - (R - f) / ln2;
     }
index e59f5f33ce6f7981cb5cc15e2a7c9fce7f0b7696..b4975a8af8d478fb4e9658b3fa94b84c87d42812 100644 (file)
@@ -116,6 +116,7 @@ static char rcsid[] = "$NetBSD: s_erf.c,v 1.8 1995/05/10 20:47:05 jtc Exp $";
 #include <float.h>
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 static const double
   tiny = 1e-300,
@@ -308,7 +309,10 @@ __erfc (double x)
   ix = hx & 0x7fffffff;
   if (ix >= 0x7ff00000)                         /* erfc(nan)=nan */
     {                                           /* erfc(+-inf)=0,2 */
-      return (double) (((u_int32_t) hx >> 31) << 1) + one / x;
+      double ret = (double) (((u_int32_t) hx >> 31) << 1) + one / x;
+      if (FIX_INT_FP_CONVERT_ZERO && ret == 0.0)
+       return 0.0;
+      return ret;
     }
 
   if (ix < 0x3feb0000)                  /* |x|<0.84375 */
index 7a6c49abf51e020b092b53fbe65c8ab4e6fa0418..3a26b18f78776608e4ceb78412ecb6fb693c12be 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 double
 __logb (double x)
@@ -41,6 +42,8 @@ __logb (double x)
        ma = __builtin_clz (ix);
       rix -= ma - 12;
     }
+  if (FIX_INT_FP_CONVERT_ZERO && rix == 1023)
+    return 0.0;
   return (double) (rix - 1023);
 }
 weak_alias (__logb, logb)
index 1daeef71071b856af974be923d677e5983e8fea9..2cd01b4a500001101584ebfc5359402ca9588c04 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 static const float
 two25      =  3.3554432000e+07, /* 0x4c000000 */
@@ -44,6 +45,8 @@ __ieee754_log10f(float x)
        i  = ((u_int32_t)k&0x80000000)>>31;
        hx = (hx&0x007fffff)|((0x7f-i)<<23);
        y  = (float)(k+i);
+       if (FIX_INT_FP_CONVERT_ZERO && y == 0.0f)
+         y = 0.0f;
        SET_FLOAT_WORD(x,hx);
        z  = y*log10_2lo + ivln10*__ieee754_logf(x);
        return  z+y*log10_2hi;
index 245be4e6f77d4c1d26534d2a29d4e41b26504cbe..857d13fb9be23b0d61954bba314d4fb9eacf7df2 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 static const float
 ln2 = 0.69314718055994530942,
@@ -57,7 +58,12 @@ __ieee754_log2f(float x)
        dk = (float)k;
        f = x-(float)1.0;
        if((0x007fffff&(15+ix))<16) {   /* |f| < 2**-20 */
-           if(f==zero) return dk;
+           if(f==zero)
+             {
+               if (FIX_INT_FP_CONVERT_ZERO && dk == 0.0f)
+                 dk = 0.0f;
+               return dk;
+             }
            R = f*f*((float)0.5-(float)0.33333333333333333*f);
            return dk-(R-f)/ln2;
        }
index 3162d81d084b78b05445328174a948a14928fc30..c8b62875035042b9289928ea641bde1d924fc683 100644 (file)
@@ -21,6 +21,7 @@ static char rcsid[] = "$NetBSD: s_erff.c,v 1.4 1995/05/10 20:47:07 jtc Exp $";
 #include <float.h>
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 static const float
 tiny       = 1e-30,
@@ -161,7 +162,10 @@ float __erfcf(float x)
        ix = hx&0x7fffffff;
        if(ix>=0x7f800000) {                    /* erfc(nan)=nan */
                                                /* erfc(+-inf)=0,2 */
-           return (float)(((u_int32_t)hx>>31)<<1)+one/x;
+           float ret = (float)(((u_int32_t)hx>>31)<<1)+one/x;
+           if (FIX_INT_FP_CONVERT_ZERO && ret == 0.0f)
+             return 0.0f;
+           return ret;
        }
 
        if(ix < 0x3f580000) {           /* |x|<0.84375 */
index ba0267ebcbffed0f4918bf0d33269a3bfce38ec0..9ae20e332aa04ef67222a37eb31e379267b87a2a 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <math.h>
 #include <math_private.h>
+#include <fix-int-fp-convert-zero.h>
 
 float
 __logbf (float x)
@@ -33,6 +34,8 @@ __logbf (float x)
          though it were normalized.  */
       rix -= __builtin_clz (ix) - 9;
     }
+  if (FIX_INT_FP_CONVERT_ZERO && rix == 127)
+    return 0.0f;
   return (float) (rix - 127);
 }
 weak_alias (__logbf, logbf)
index 455c645561e703544709375def9124b96d14a882..82d889d14ed9a0fd61c9d7f94f067bac9bce2109 100644 (file)
 #include <math.h>
 #include <math_private.h>
 #include <math_ldbl_opt.h>
+#include <fix-int-fp-convert-zero.h>
 
 /* Evaluate P[n] x^n  +  P[n-1] x^(n-1)  +  ...  +  P[0] */
 
@@ -839,7 +840,10 @@ __erfcl (long double x)
   if (ix >= 0x7ff00000)
     {                          /* erfc(nan)=nan */
       /* erfc(+-inf)=0,2 */
-      return (long double) ((hx >> 31) << 1) + one / x;
+      long double ret = (long double) ((hx >> 31) << 1) + one / x;
+      if (FIX_INT_FP_CONVERT_ZERO && ret == 0.0L)
+       return 0.0L;
+      return ret;
     }
 
   if (ix < 0x3fd00000) /* |x| <1/4 */
index 22e5fc24c0543474c9ac00b2604420e9dcba7af7..3c07c5e8e2bf6a4da8501dd4d7b9a04931f434fd 100644 (file)
@@ -22,6 +22,7 @@
 #include <math.h>
 #include <math_private.h>
 #include <math_ldbl_opt.h>
+#include <fix-int-fp-convert-zero.h>
 
 long double
 __logbl (long double x)
@@ -53,6 +54,8 @@ __logbl (long double x)
       if ((hxs ^ lx) < 0 && (lx & 0x7fffffffffffffffLL) != 0)
        rhx--;
     }
+  if (FIX_INT_FP_CONVERT_ZERO && rhx == 1023)
+    return 0.0L;
   return (long double) (rhx - 1023);
 }
 #ifndef __logbl
diff --git a/sysdeps/powerpc/powerpc32/fpu/configure b/sysdeps/powerpc/powerpc32/fpu/configure
new file mode 100644 (file)
index 0000000..69a151b
--- /dev/null
@@ -0,0 +1,29 @@
+# This file is generated from configure.ac by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc/powerpc32/fpu.
+
+# Test whether integer to floating point conversions use fcfid.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fcfid use" >&5
+$as_echo_n "checking for fcfid use... " >&6; }
+if ${libc_cv_ppc_fcfid+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  echo 'double foo (int x) { return (double) x; }' > conftest.c
+libc_cv_ppc_fcfid=no
+if { ac_try='${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+  if grep '[   ]fcfid' conftest.s > /dev/null 2>&1; then
+    libc_cv_ppc_fcfid=yes
+  fi
+fi
+rm -rf conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc_fcfid" >&5
+$as_echo "$libc_cv_ppc_fcfid" >&6; }
+if test $libc_cv_ppc_fcfid = yes; then
+  $as_echo "#define HAVE_PPC_FCFID 1" >>confdefs.h
+
+fi
diff --git a/sysdeps/powerpc/powerpc32/fpu/configure.ac b/sysdeps/powerpc/powerpc32/fpu/configure.ac
new file mode 100644 (file)
index 0000000..e596e79
--- /dev/null
@@ -0,0 +1,18 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc/powerpc32/fpu.
+
+# Test whether integer to floating point conversions use fcfid.
+AC_CACHE_CHECK([for fcfid use], [libc_cv_ppc_fcfid], [dnl
+echo 'double foo (int x) { return (double) x; }' > conftest.c
+libc_cv_ppc_fcfid=no
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+changequote(,)dnl
+  if grep '[   ]fcfid' conftest.s > /dev/null 2>&1; then
+    libc_cv_ppc_fcfid=yes
+  fi
+changequote([,])dnl
+fi
+rm -rf conftest*])
+if test $libc_cv_ppc_fcfid = yes; then
+  AC_DEFINE([HAVE_PPC_FCFID])
+fi
diff --git a/sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h b/sysdeps/powerpc/powerpc32/fpu/fix-int-fp-convert-zero.h
new file mode 100644 (file)
index 0000000..9ab8fad
--- /dev/null
@@ -0,0 +1,28 @@
+/* Fix for conversion of integer 0 to floating point.  PowerPC version.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef FIX_INT_FP_CONVERT_ZERO_H
+#define FIX_INT_FP_CONVERT_ZERO_H      1
+
+/* The code sequences GCC generates for conversion of integers to
+   floating point result in -0 instead of +0 in FE_DOWNWARD mode when
+   the fcfid instruction is not used, as of GCC 5.  See
+   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67771>.  */
+#define FIX_INT_FP_CONVERT_ZERO (!HAVE_PPC_FCFID)
+
+#endif /* fix-int-fp-convert-zero.h */