Message ID | 20220821104446.46521-1-michael.hudson@canonical.com |
---|---|
State | New |
Headers | show |
Series | Avoid undefined behaviour in ibm128 implementation of llroundl | expand |
Disregard this, I hadn't run all the tests I thought I had, sorry about that. On Sun, 21 Aug 2022 at 22:45, Michael Hudson-Doyle < michael.hudson@canonical.com> wrote: > Detecting an overflow edge case depended on signed overflow of a long > long. Replace the signed long long with unsigned and cast it back to > unsigned before comparisons (which is implementation defined behaviour, > but I guess glibc does not support any one's complement > architectures...). > > BZ #29488 > --- > sysdeps/ieee754/ldbl-128ibm/s_llroundl.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c > b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c > index d85154e73a..e8117bfc2b 100644 > --- a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c > +++ b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c > @@ -28,7 +28,8 @@ long long > __llroundl (long double x) > { > double xh, xl; > - long long res, hi, lo; > + unsigned long long res; > + long long hi, lo; > > ldbl_unpack (x, &xh, &xl); > > @@ -69,7 +70,7 @@ __llroundl (long double x) > res = hi + lo; > > /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */ > - if (__glibc_unlikely (((~(hi ^ lo) & (res ^ hi)) < 0))) > + if (__glibc_unlikely (((~(hi ^ lo) & (((long long)res) ^ hi)) < 0))) > goto overflow; > > xh -= lo; > @@ -95,7 +96,7 @@ __llroundl (long double x) > res -= 1; > } > > - if (__glibc_unlikely (((~(hi ^ (res - hi)) & (res ^ hi)) < 0))) > + if (__glibc_unlikely (((~(hi ^ (((long long)res) - hi)) & (((long > long)res) ^ hi)) < 0))) > goto overflow; > > return res; > -- > 2.34.1 > >
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c index d85154e73a..e8117bfc2b 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c @@ -28,7 +28,8 @@ long long __llroundl (long double x) { double xh, xl; - long long res, hi, lo; + unsigned long long res; + long long hi, lo; ldbl_unpack (x, &xh, &xl); @@ -69,7 +70,7 @@ __llroundl (long double x) res = hi + lo; /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */ - if (__glibc_unlikely (((~(hi ^ lo) & (res ^ hi)) < 0))) + if (__glibc_unlikely (((~(hi ^ lo) & (((long long)res) ^ hi)) < 0))) goto overflow; xh -= lo; @@ -95,7 +96,7 @@ __llroundl (long double x) res -= 1; } - if (__glibc_unlikely (((~(hi ^ (res - hi)) & (res ^ hi)) < 0))) + if (__glibc_unlikely (((~(hi ^ (((long long)res) - hi)) & (((long long)res) ^ hi)) < 0))) goto overflow; return res;