aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-10-01 08:30:06 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-10-01 08:30:06 +0000
commitbec749fda1cbc1934f7e58dd2763603f4f207f26 (patch)
tree680a53e980c97e223c0e10353d83a41a5b43fdd0 /sysdeps
parent8ec5b01346114da38e806ca1867da688d3a360e2 (diff)
downloadglibc-bec749fda1cbc1934f7e58dd2763603f4f207f26.tar
glibc-bec749fda1cbc1934f7e58dd2763603f4f207f26.tar.gz
glibc-bec749fda1cbc1934f7e58dd2763603f4f207f26.tar.bz2
glibc-bec749fda1cbc1934f7e58dd2763603f4f207f26.zip
Fix sign of inexact zero return from fma (bug 14645).
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/ieee754/dbl-64/s_fma.c5
-rw-r--r--sysdeps/ieee754/ldbl-128/s_fmal.c5
-rw-r--r--sysdeps/ieee754/ldbl-96/s_fmal.c5
3 files changed, 15 insertions, 0 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_fma.c b/sysdeps/ieee754/dbl-64/s_fma.c
index c9809fb180..5e21461a4b 100644
--- a/sysdeps/ieee754/dbl-64/s_fma.c
+++ b/sysdeps/ieee754/dbl-64/s_fma.c
@@ -49,6 +49,11 @@ __fma (double x, double y, double z)
&& u.ieee.exponent != 0x7ff
&& v.ieee.exponent != 0x7ff)
return (z + x) + y;
+ /* If z is zero and x are y are nonzero, compute the result
+ as x * y to avoid the wrong sign of a zero result if x * y
+ underflows to 0. */
+ if (z == 0 && x != 0 && y != 0)
+ return x * y;
/* If x or y or z is Inf/NaN, or if fma will certainly overflow,
or if x * y is less than half of DBL_DENORM_MIN,
compute as x * y + z. */
diff --git a/sysdeps/ieee754/ldbl-128/s_fmal.c b/sysdeps/ieee754/ldbl-128/s_fmal.c
index df68ade435..46b3d81ce5 100644
--- a/sysdeps/ieee754/ldbl-128/s_fmal.c
+++ b/sysdeps/ieee754/ldbl-128/s_fmal.c
@@ -50,6 +50,11 @@ __fmal (long double x, long double y, long double z)
&& u.ieee.exponent != 0x7fff
&& v.ieee.exponent != 0x7fff)
return (z + x) + y;
+ /* If z is zero and x are y are nonzero, compute the result
+ as x * y to avoid the wrong sign of a zero result if x * y
+ underflows to 0. */
+ if (z == 0 && x != 0 && y != 0)
+ return x * y;
/* If x or y or z is Inf/NaN, or if fma will certainly overflow,
or if x * y is less than half of LDBL_DENORM_MIN,
compute as x * y + z. */
diff --git a/sysdeps/ieee754/ldbl-96/s_fmal.c b/sysdeps/ieee754/ldbl-96/s_fmal.c
index c27b0bd852..d125124286 100644
--- a/sysdeps/ieee754/ldbl-96/s_fmal.c
+++ b/sysdeps/ieee754/ldbl-96/s_fmal.c
@@ -50,6 +50,11 @@ __fmal (long double x, long double y, long double z)
&& u.ieee.exponent != 0x7fff
&& v.ieee.exponent != 0x7fff)
return (z + x) + y;
+ /* If z is zero and x are y are nonzero, compute the result
+ as x * y to avoid the wrong sign of a zero result if x * y
+ underflows to 0. */
+ if (z == 0 && x != 0 && y != 0)
+ return x * y;
/* If x or y or z is Inf/NaN, or if fma will certainly overflow,
or if x * y is less than half of LDBL_DENORM_MIN,
compute as x * y + z. */