166 lines
5.9 KiB
Diff
166 lines
5.9 KiB
Diff
|
From 548cc83c38a91852b1e44045ead3d20ccd5db4cf Mon Sep 17 00:00:00 2001
|
||
|
From: Joseph Myers <joseph@codesourcery.com>
|
||
|
Date: Thu, 28 Sep 2017 01:59:02 +0000
|
||
|
Subject: [PATCH 42] Fix nearbyint arithmetic moved before feholdexcept (bug
|
||
|
22225).
|
||
|
|
||
|
In <https://sourceware.org/ml/libc-alpha/2013-05/msg00722.html> I
|
||
|
remarked on the possibility of arithmetic in various nearbyint
|
||
|
implementations being scheduled before feholdexcept calls, resulting
|
||
|
in spurious "inexact" exceptions.
|
||
|
|
||
|
I'm now actually observing this occurring in glibc built for ARM with
|
||
|
GCC 7 (in fact, both copies of the same addition/subtraction sequence
|
||
|
being combined and moved out before the conditionals and
|
||
|
feholdexcept/fesetenv pairs), resulting in test failures.
|
||
|
|
||
|
This patch makes the nearbyint implementations with this particular
|
||
|
feholdexcept / arithmetic / fesetenv pattern consistently use
|
||
|
math_opt_barrier on the function argument when first used in
|
||
|
arithmetic, and also consistently use math_force_eval before fesetenv
|
||
|
(the latter was generally already done, but the dbl-64/wordsize-64
|
||
|
implementation used math_opt_barrier instead, and as
|
||
|
math_opt_barrier's intended effect is through its output value being
|
||
|
used, such a use that doesn't use the return value is suspect).
|
||
|
|
||
|
Tested for x86_64 (--disable-multi-arch so more of these
|
||
|
implementations get used), and for ARM in a configuration where I saw
|
||
|
the problem scheduling.
|
||
|
|
||
|
[BZ #22225]
|
||
|
* sysdeps/ieee754/dbl-64/s_nearbyint.c (__nearbyint): Use
|
||
|
math_opt_barrier on argument when doing arithmetic on it.
|
||
|
* sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c (__nearbyint):
|
||
|
Likewise. Use math_force_eval not math_opt_barrier after
|
||
|
arithmetic.
|
||
|
* sysdeps/ieee754/flt-32/s_nearbyintf.c (__nearbyintf): Use
|
||
|
math_opt_barrier on argument when doing arithmetic on it.
|
||
|
* sysdeps/ieee754/ldbl-128/s_nearbyintl.c (__nearbyintl):
|
||
|
Likewise.
|
||
|
|
||
|
(cherry picked from commit f124cb381116b5809de198327690ad0bd8d1478e)
|
||
|
---
|
||
|
ChangeLog | 13 +++++++++++++
|
||
|
sysdeps/ieee754/dbl-64/s_nearbyint.c | 4 ++--
|
||
|
sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c | 8 ++++----
|
||
|
sysdeps/ieee754/flt-32/s_nearbyintf.c | 4 ++--
|
||
|
sysdeps/ieee754/ldbl-128/s_nearbyintl.c | 4 ++--
|
||
|
5 files changed, 23 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/ChangeLog b/ChangeLog
|
||
|
index 382674d5a3..992722acdb 100644
|
||
|
--- a/ChangeLog
|
||
|
+++ b/ChangeLog
|
||
|
@@ -1,3 +1,16 @@
|
||
|
+2017-09-28 Joseph Myers <joseph@codesourcery.com>
|
||
|
+
|
||
|
+ [BZ #22225]
|
||
|
+ * sysdeps/ieee754/dbl-64/s_nearbyint.c (__nearbyint): Use
|
||
|
+ math_opt_barrier on argument when doing arithmetic on it.
|
||
|
+ * sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c (__nearbyint):
|
||
|
+ Likewise. Use math_force_eval not math_opt_barrier after
|
||
|
+ arithmetic.
|
||
|
+ * sysdeps/ieee754/flt-32/s_nearbyintf.c (__nearbyintf): Use
|
||
|
+ math_opt_barrier on argument when doing arithmetic on it.
|
||
|
+ * sysdeps/ieee754/ldbl-128/s_nearbyintl.c (__nearbyintl):
|
||
|
+ Likewise.
|
||
|
+
|
||
|
2017-09-22 Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
|
||
|
|
||
|
[BZ #22146]
|
||
|
diff --git a/sysdeps/ieee754/dbl-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/s_nearbyint.c
|
||
|
index dec0c5d6ee..6e3f8316b1 100644
|
||
|
--- a/sysdeps/ieee754/dbl-64/s_nearbyint.c
|
||
|
+++ b/sysdeps/ieee754/dbl-64/s_nearbyint.c
|
||
|
@@ -48,7 +48,7 @@ __nearbyint (double x)
|
||
|
if (j0 < 0)
|
||
|
{
|
||
|
libc_feholdexcept (&env);
|
||
|
- w = TWO52[sx] + x;
|
||
|
+ w = TWO52[sx] + math_opt_barrier (x);
|
||
|
t = w - TWO52[sx];
|
||
|
math_force_eval (t);
|
||
|
libc_fesetenv (&env);
|
||
|
@@ -65,7 +65,7 @@ __nearbyint (double x)
|
||
|
return x; /* x is integral */
|
||
|
}
|
||
|
libc_feholdexcept (&env);
|
||
|
- w = TWO52[sx] + x;
|
||
|
+ w = TWO52[sx] + math_opt_barrier (x);
|
||
|
t = w - TWO52[sx];
|
||
|
math_force_eval (t);
|
||
|
libc_fesetenv (&env);
|
||
|
diff --git a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
|
||
|
index 8293819981..7d135b54e4 100644
|
||
|
--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
|
||
|
+++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
|
||
|
@@ -42,9 +42,9 @@ __nearbyint(double x)
|
||
|
if(__builtin_expect(j0<52, 1)) {
|
||
|
if(j0<0) {
|
||
|
libc_feholdexcept (&env);
|
||
|
- double w = TWO52[sx]+x;
|
||
|
+ double w = TWO52[sx] + math_opt_barrier (x);
|
||
|
double t = w-TWO52[sx];
|
||
|
- math_opt_barrier(t);
|
||
|
+ math_force_eval (t);
|
||
|
libc_fesetenv (&env);
|
||
|
return __copysign (t, x);
|
||
|
}
|
||
|
@@ -53,9 +53,9 @@ __nearbyint(double x)
|
||
|
else return x; /* x is integral */
|
||
|
}
|
||
|
libc_feholdexcept (&env);
|
||
|
- double w = TWO52[sx]+x;
|
||
|
+ double w = TWO52[sx] + math_opt_barrier (x);
|
||
|
double t = w-TWO52[sx];
|
||
|
- math_opt_barrier (t);
|
||
|
+ math_force_eval (t);
|
||
|
libc_fesetenv (&env);
|
||
|
return t;
|
||
|
}
|
||
|
diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c
|
||
|
index 5aebefafcf..b06df6b3c8 100644
|
||
|
--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c
|
||
|
+++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c
|
||
|
@@ -37,7 +37,7 @@ __nearbyintf(float x)
|
||
|
if(j0<23) {
|
||
|
if(j0<0) {
|
||
|
libc_feholdexceptf (&env);
|
||
|
- w = TWO23[sx]+x;
|
||
|
+ w = TWO23[sx] + math_opt_barrier (x);
|
||
|
t = w-TWO23[sx];
|
||
|
math_force_eval (t);
|
||
|
libc_fesetenvf (&env);
|
||
|
@@ -50,7 +50,7 @@ __nearbyintf(float x)
|
||
|
else return x; /* x is integral */
|
||
|
}
|
||
|
libc_feholdexceptf (&env);
|
||
|
- w = TWO23[sx]+x;
|
||
|
+ w = TWO23[sx] + math_opt_barrier (x);
|
||
|
t = w-TWO23[sx];
|
||
|
math_force_eval (t);
|
||
|
libc_fesetenvf (&env);
|
||
|
diff --git a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
|
||
|
index 1565a8183f..98a33d24a7 100644
|
||
|
--- a/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
|
||
|
+++ b/sysdeps/ieee754/ldbl-128/s_nearbyintl.c
|
||
|
@@ -45,7 +45,7 @@ _Float128 __nearbyintl(_Float128 x)
|
||
|
if(j0<112) {
|
||
|
if(j0<0) {
|
||
|
feholdexcept (&env);
|
||
|
- w = TWO112[sx]+x;
|
||
|
+ w = TWO112[sx] + math_opt_barrier (x);
|
||
|
t = w-TWO112[sx];
|
||
|
math_force_eval (t);
|
||
|
fesetenv (&env);
|
||
|
@@ -58,7 +58,7 @@ _Float128 __nearbyintl(_Float128 x)
|
||
|
else return x; /* x is integral */
|
||
|
}
|
||
|
feholdexcept (&env);
|
||
|
- w = TWO112[sx]+x;
|
||
|
+ w = TWO112[sx] + math_opt_barrier (x);
|
||
|
t = w-TWO112[sx];
|
||
|
math_force_eval (t);
|
||
|
fesetenv (&env);
|
||
|
|