From 178df332f10bda54d58513e7cca79538f080606a Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jul 14 2017 22:06:38 +0000 Subject: import glibc-2.17-157.el7_3.5 --- diff --git a/SOURCES/glibc-rh1463274-1.patch b/SOURCES/glibc-rh1463274-1.patch new file mode 100644 index 0000000..eba9b41 --- /dev/null +++ b/SOURCES/glibc-rh1463274-1.patch @@ -0,0 +1,158 @@ +commit 38f3458175ecf7c3588bd5b6e465f4d9205fbe1c +Author: Adhemerval Zanella +Date: Wed Jan 8 05:10:41 2014 -0600 + + PowerPC: remove wrong truncl implementation for PowerPC64 + + The truncl assembly implementation (sysdeps/powerpc/powerpc64/fpu/s_truncl.S) + returns wrong results for some inputs where first double is a exact integer + and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_truncl.c instead it fixes tgammal + issues regarding wrong result sign. + +Index: b/sysdeps/ieee754/ldbl-128ibm/s_truncl.c +=================================================================== +--- a/sysdeps/ieee754/ldbl-128ibm/s_truncl.c ++++ b/sysdeps/ieee754/ldbl-128ibm/s_truncl.c +@@ -17,9 +17,6 @@ + License along with the GNU C Library; if not, see + . */ + +-/* This has been coded in assembler because GCC makes such a mess of it +- when it's coded in C. */ +- + #include + #include + #include +Index: b/sysdeps/powerpc/powerpc64/fpu/s_truncl.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_truncl.S ++++ /dev/null +@@ -1,120 +0,0 @@ +-/* long double trunc function. +- IBM extended format long double version. +- Copyright (C) 2004, 2006 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 +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +-.LC1: /* 0.5 */ +- .tc FD_3fe00000_0[TC],0x3fe0000000000000 +- .section ".text" +- +-/* long double [fp1,fp2] truncl (long double x [fp1,fp2]) */ +- +-ENTRY (__truncl) +- mffs fp11 /* Save current FPU rounding mode. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fabs fp9,fp2 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- ble- cr6,.L1 +- fneg fp2,fp12 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */ +-.L0: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +-.L1: +- fneg fp2,fp12 +- bge- cr6,.L0 /* if (x < 0.0) */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */ +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. In this case we have to round the low +- double and handle any adjustment to the high double that may be +- caused by rounding (up). This is complicated by the fact that the +- high double may already be rounded and the low double may have the +- opposite sign to compensate.This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = rint(x1); +- y_high = x0 + r1; +- y_low = x0 - y_high + r1; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ +- bgelr- cr7 /* return x; */ +- beqlr- cr0 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- +- bng- cr6,.L6 /* if (x > 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- fadd fp8,fp8,fp8 /* tau++; Make tau even */ +- bng cr5,.L4 /* if (x_low > 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L5 +-.L4: /* if (x_low < 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L5: +- fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L9 +-.L6: /* if (x < 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- fadd fp8,fp8,fp8 /* tau++; Make tau even */ +- bnl cr5,.L7 /* if (x_low < 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L8 +-.L7: /* if (x_low > 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L8: +- fsub fp5,fp4,fp13 /* r1-= TWO52; */ +- fadd fp5,fp5,fp13 /* r1+= TWO52; */ +-.L9: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ +- fadd fp2,fp2,fp5 +- blr +-END (__truncl) +- +-long_double_symbol (libm, __truncl, truncl) diff --git a/SOURCES/glibc-rh1463274-2.patch b/SOURCES/glibc-rh1463274-2.patch new file mode 100644 index 0000000..bd41b69 --- /dev/null +++ b/SOURCES/glibc-rh1463274-2.patch @@ -0,0 +1,179 @@ +Backport of this upstream commit (with libm-test.inc adjustments): + +commit 374f7f61214967bb4e2257695aeeeecc2a77f369 +Author: Adhemerval Zanella +Date: Fri Mar 14 07:35:43 2014 -0500 + + PowerPC: remove wrong ceill implementation for PowerPC64 + + The ceill assembly implementation (sysdeps/powerpc/powerpc64/fpu/s_ceill.S) + returns wrong results for some inputs where first double is a exact + integer and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_ceill.c instead fixes the failing math. + + Fixes BZ#16701. + +Index: b/math/libm-test.inc +=================================================================== +--- a/math/libm-test.inc ++++ b/math/libm-test.inc +@@ -2241,6 +2241,15 @@ ceil_test (void) + TEST_f_f (ceil, -72057594037927936.75L, -72057594037927936.0L); + TEST_f_f (ceil, -72057594037927937.5L, -72057594037927937.0L); + ++ /* Check cases where first double is a exact integer higher than 2^52 and ++ the precision is determined by second long double for IBM long double. */ ++ TEST_f_f (ceil, 34503599627370498.515625L, 34503599627370499.0L); ++ TEST_f_f (ceil, -34503599627370498.515625L, -34503599627370498.0L); ++# if LDBL_MANT_DIG >= 106 ++ TEST_f_f (ceil, 1192568192774434123539907640624.484375L, 1192568192774434123539907640625.0L); ++ TEST_f_f (ceil, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L); ++# endif ++ + TEST_f_f (ceil, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L); + TEST_f_f (ceil, 10141204801825835211973625643008.25L, 10141204801825835211973625643009.0L); + TEST_f_f (ceil, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L); +Index: b/sysdeps/powerpc/powerpc64/fpu/s_ceill.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_ceill.S ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* s_ceill.S IBM extended format long double version. +- Copyright (C) 2004, 2006 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 +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +- +- .section ".text" +- +-/* long double [fp1,fp2] ceill (long double x [fp1,fp2]) +- IEEE 1003.1 ceil function. +- +- PowerPC64 long double uses the IBM extended format which is +- represented two 64-floating point double values. The values are +- non-overlapping giving an effective precision of 106 bits. The first +- double contains the high order bits of mantisa and is always ceiled +- to represent a normal ceiling of long double to double. Since the +- long double value is sum of the high and low values, the low double +- normally has the opposite sign to compensate for the this ceiling. +- +- For long double there are two cases: +- 1) |x| < 2**52, all the integer bits are in the high double. +- ceil the high double and set the low double to -0.0. +- 2) |x| >= 2**52, ceiling involves both doubles. +- See the comment before lable .L2 for details. +- */ +- +-ENTRY (__ceill) +- mffs fp11 /* Save current FPU rounding mode. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fabs fp9,fp2 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- fneg fp2,fp12 +- ble- cr6,.L1 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) */ +-.L0: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr /* x = 0.0; */ +-.L1: +- bge- cr6,.L0 /* if (x < 0.0) */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fnabs fp1,fp1 /* if (x == 0.0) */ +- blr /* x = -0.0; */ +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. In this case we have to round the low +- double and handle any adjustment to the high double that may be +- caused by rounding (up). This is complicated by the fact that the +- high double may already be rounded and the low double may have the +- opposite sign to compensate.This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = rint(x1); +- y_high = x0 + r1; +- y_low = x0 - y_high + r1; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ +- bgelr- cr7 /* return x; */ +- beqlr- cr0 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- +- bng- cr6,.L6 /* if (x > 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bng cr5,.L4 /* if (x_low > 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L5 +-.L4: /* if (x_low < 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L5: +- fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L9 +-.L6: /* if (x < 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bnl cr5,.L7 /* if (x_low < 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L8 +-.L7: /* if (x_low > 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L8: +- fsub fp5,fp4,fp13 /* r1-= TWO52; */ +- fadd fp5,fp5,fp13 /* r1+= TWO52; */ +-.L9: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ +- fadd fp2,fp2,fp5 +- blr +-END (__ceill) +- +-long_double_symbol (libm, __ceill, ceill) diff --git a/SOURCES/glibc-rh1463274-3.patch b/SOURCES/glibc-rh1463274-3.patch new file mode 100644 index 0000000..535be75 --- /dev/null +++ b/SOURCES/glibc-rh1463274-3.patch @@ -0,0 +1,163 @@ +Backport of this upstream commit (with libm-test.inc adjustments): + +commit 98fb27a373f37554232e0060eef1a5bb00a07eb0 +Author: Adhemerval Zanella +Date: Fri Mar 14 12:27:52 2014 -0500 + + PowerPC: remove wrong nearbyintl implementation for PPC64 + + The nearbyintl assembly implementation + (sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S) + returns wrong results for some inputs where first double is a exact + integer and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c instead fixes the failing + math. + + Fixes BZ#16706. + +Index: b/math/libm-test.inc +=================================================================== +--- a/math/libm-test.inc ++++ b/math/libm-test.inc +@@ -7619,6 +7619,16 @@ nearbyint_test (void) + TEST_f_f (nearbyint, -562949953421312.75, -562949953421313.0); + TEST_f_f (nearbyint, -1125899906842624.75, -1125899906842625.0); + #endif ++#ifdef TEST_LDOUBLE ++ /* Check cases where first double is a exact integer higher than 2^52 and ++ the precision is determined by second long double for IBM long double. */ ++ TEST_f_f (nearbyint, 34503599627370498.515625L, 34503599627370499.0L); ++ TEST_f_f (nearbyint, -34503599627370498.515625L, -34503599627370499.0L); ++# if LDBL_MANT_DIG >= 106 ++ TEST_f_f (nearbyint, 1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L); ++ TEST_f_f (nearbyint, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L); ++# endif ++#endif + + END (nearbyint); + } +Index: b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S ++++ /dev/null +@@ -1,113 +0,0 @@ +-/* nearbyint long double. +- IBM extended format long double version. +- Copyright (C) 2004, 2006 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 +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +- .section ".text" +- +-/* long double [fp1,fp2] nearbyintl (long double x [fp1,fp2]) +- IEEE 1003.1 nearbyintl function. nearbyintl is simular to the rintl +- but does raise the "inexact" exception. This implementation is +- based on rintl but explicitly maskes the inexact exception on entry +- and clears any pending inexact before restoring the exception mask +- on exit. +- +- PowerPC64 long double uses the IBM extended format which is +- represented two 64-floating point double values. The values are +- non-overlapping giving an effective precision of 106 bits. The first +- double contains the high order bits of mantisa and is always rounded +- to represent a normal rounding of long double to double. Since the +- long double value is sum of the high and low values, the low double +- normally has the opposite sign to compensate for the this rounding. +- +- For long double there are two cases: +- 1) |x| < 2**52, all the integer bits are in the high double. +- floor the high double and set the low double to -0.0. +- 2) |x| >= 2**52, Rounding involves both doubles. +- See the comment before lable .L2 for details. +- */ +-ENTRY (__nearbyintl) +- mffs fp11 /* Save current FPSCR. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- mtfsb0 28 /* Disable "inexact" exceptions. */ +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fabs fp9,fp2 +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- fmr fp2,fp12 +- bng- cr6,.L4 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- b .L9 +-.L4: +- bnl- cr6,.L9 /* if (x < 0.0) */ +- fsub fp1,fp13,fp1 /* x = TWO52 - x; */ +- fsub fp0,fp1,fp13 /* x = - (x - TWO52); */ +- fneg fp1,fp0 +-.L9: +- mtfsb0 6 /* Clear any pending "inexact" exceptions. */ +- mtfsf 0x01,fp11 /* restore exception mask. */ +- blr +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = nearbyint(x1); +- y_high = x0 + r1; +- y_low = r1 - tau; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- bge- cr7,.L9 /* return x; */ +- beq- cr0,.L9 +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +- +- fcmpu cr6,fp4,fp12 /* if (x1 > 0.0) */ +- bng- cr6,.L8 +- fadd fp5,fp4,fp13 /* r1 = x1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L6 +-.L8: +- fmr fp5,fp4 +- bge- cr6,.L6 /* if (x1 < 0.0) */ +- fsub fp5,fp13,fp4 /* r1 = TWO52 - x1; */ +- fsub fp0,fp5,fp13 /* r1 = - (r1 - TWO52); */ +- fneg fp5,fp0 +-.L6: +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp5,fp8 /* y_low = r1 - tau; */ +- b .L9 +-END (__nearbyintl) +- +-long_double_symbol (libm, __nearbyintl, nearbyintl) diff --git a/SOURCES/glibc-rh1463274-4.patch b/SOURCES/glibc-rh1463274-4.patch new file mode 100644 index 0000000..f4d731d --- /dev/null +++ b/SOURCES/glibc-rh1463274-4.patch @@ -0,0 +1,180 @@ +Backport of this upstream commit (with libm-test.inc adjustments): + +commit c7de50250367167d8c9f35594b264f6a0af8dd0c +Author: Adhemerval Zanella +Date: Fri Mar 14 12:49:45 2014 -0500 + + PowerPC: remove wrong roundl implementation for PowerPC64 + + The roundl assembly implementation + (sysdeps/powerpc/powerpc64/fpu/s_roundl.S) + returns wrong results for some inputs where first double is a exact + integer and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_roundl.c instead fixes the failing math. + + This fixes 16707. + +Index: b/math/libm-test.inc +=================================================================== +--- a/math/libm-test.inc ++++ b/math/libm-test.inc +@@ -9268,6 +9268,15 @@ round_test (void) + TEST_f_f (round, -72057594037927936.75L, -72057594037927937.0L); + TEST_f_f (round, -72057594037927937.5L, -72057594037927938.0L); + ++ /* Check cases where first double is a exact integer higher than 2^52 and ++ the precision is determined by second long double for IBM long double. */ ++ TEST_f_f (round, 34503599627370498.515625L, 34503599627370499.0L); ++ TEST_f_f (round, -34503599627370498.515625L, -34503599627370499.0L); ++# if LDBL_MANT_DIG >= 106 ++ TEST_f_f (round, 1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L); ++ TEST_f_f (round, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L); ++# endif ++ + TEST_f_f (round, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L); + TEST_f_f (round, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L); + TEST_f_f (round, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L); +Index: b/sysdeps/powerpc/powerpc64/fpu/s_roundl.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_roundl.S ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* long double round function. +- IBM extended format long double version. +- Copyright (C) 2004, 2006 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 +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +-.LC1: /* 0.5 */ +- .tc FD_3fe00000_0[TC],0x3fe0000000000000 +- .section ".text" +- +-/* long double [fp1,fp2] roundl (long double x [fp1,fp2]) +- IEEE 1003.1 round function. IEEE specifies "round to the nearest +- integer value, rounding halfway cases away from zero, regardless of +- the current rounding mode." However PowerPC Architecture defines +- "Round to Nearest" as "Choose the best approximation. In case of a +- tie, choose the one that is even (least significant bit o).". +- So we can't use the PowerPC "Round to Nearest" mode. Instead we set +- "Round toward Zero" mode and round by adding +-0.5 before rounding +- to the integer value. */ +- +-ENTRY (__roundl) +- mffs fp11 /* Save current FPU rounding mode. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fabs fp9,fp2 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- lfd fp10,.LC1@toc(2) +- ble- cr6,.L1 +- fneg fp2,fp12 +- fadd fp1,fp1,fp10 /* x+= 0.5; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */ +-.L0: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +-.L1: +- fsub fp9,fp1,fp10 /* x-= 0.5; */ +- fneg fp2,fp12 +- bge- cr6,.L0 /* if (x < 0.0) */ +- fsub fp1,fp9,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */ +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. In this case we have to round the low +- double and handle any adjustment to the high double that may be +- caused by rounding (up). This is complicated by the fact that the +- high double may already be rounded and the low double may have the +- opposite sign to compensate.This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = rint(x1); +- y_high = x0 + r1; +- y_low = x0 - y_high + r1; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ +- lfd fp10,.LC1@toc(2) +- bgelr- cr7 /* return x; */ +- beqlr- cr0 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- +- bng- cr6,.L6 /* if (x > 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bng cr5,.L4 /* if (x_low > 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L5 +-.L4: /* if (x_low < 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L5: +- fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */ +- fadd fp5,fp5,fp13 /* r1 = r1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L9 +-.L6: /* if (x < 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bnl cr5,.L7 /* if (x_low < 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L8 +-.L7: /* if (x_low > 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L8: +- fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */ +- fsub fp5,fp5,fp13 /* r1-= TWO52; */ +- fadd fp5,fp5,fp13 /* r1+= TWO52; */ +-.L9: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ +- fadd fp2,fp2,fp5 +- blr +-END (__roundl) +- +-long_double_symbol (libm, __roundl, roundl) diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index a069c89..5f0b1a4 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.17-c758a686 %define glibcversion 2.17 -%define glibcrelease 157%{?dist}.4 +%define glibcrelease 157%{?dist}.5 ############################################################################## # We support the following options: # --with/--without, @@ -925,6 +925,12 @@ Patch1755: glibc-rh1298526-4.patch # RHBZ #1350733 locale-archive.tmpl cannot be processed by build-locale-archive Patch1756: glibc-rh1350733-1.patch +# RHBZ #:1463274 Rounding issues on POWER +Patch1857: glibc-rh1463274-1.patch +Patch1858: glibc-rh1463274-2.patch +Patch1859: glibc-rh1463274-3.patch +Patch1860: glibc-rh1463274-4.patch + ############################################################################## # # Patches submitted, but not yet approved upstream. @@ -1819,6 +1825,11 @@ package or when debugging this package. %patch1755 -p1 %patch1756 -p1 +%patch1857 -p1 +%patch1858 -p1 +%patch1859 -p1 +%patch1860 -p1 + ############################################################################## # %%prep - Additional prep required... ############################################################################## @@ -2965,6 +2976,9 @@ rm -f *.filelist* %endif %changelog +* Tue Jun 20 2017 Florian Weimer - 2.17-157.5 +- Rounding issues on POWER (#1463274) + * Fri May 26 2017 Florian Weimer - 2.17-157.4 - Avoid large allocas in the dynamic linker (#1452720)