> Date: Thu, 14 Oct 2021 22:23:25 +0200 > From: Alexander Bluhm <alexander.bl...@gmx.net> > > On Thu, Oct 14, 2021 at 01:15:56AM +0200, Mark Kettenis wrote: > > Currently the lib/libm/msun/run-lrint_test regress fails on powerpc64 > > and other platforms. Our implementation came from NetBSD, but NetBSD > > switched to the implementation from FreeBSD some time ago. That is > > the same implementation that we already use for lrintl(3) and > > llrintl(3). > > > > Diff below makes us use that implementation for lrint(3), lrintf(3), > > llrint(3) and llrintf(3) as well. This makes the regress test pass on > > powerpc64. > > > > ok? > > libm Tests on powerpc64 pass now. > amd64 and i386 still passing. > arm64 and sparc64 still failing.
The remaining arm64 failures are for the "long double" versions. The problem there is that "long double" is implemented as soft-float and the soft-float implementation in libcompiler_rt doesn't set the appropriate floating-point status flags. I suspect that the sparc64 failures are similar since it is in the same boat (but uses libgcc of course). So don't expect this to be fixed anytime soon. > So it is an improvement. > > OK bluhm@ > > > Index: lib/libm/src/s_llrint.c > > =================================================================== > > RCS file: /cvs/src/lib/libm/src/s_llrint.c,v > > retrieving revision 1.6 > > diff -u -p -r1.6 s_llrint.c > > --- lib/libm/src/s_llrint.c 12 Sep 2016 19:47:02 -0000 1.6 > > +++ lib/libm/src/s_llrint.c 13 Oct 2021 23:12:11 -0000 > > @@ -1,14 +1,12 @@ > > -/* $OpenBSD: s_llrint.c,v 1.6 2016/09/12 19:47:02 guenther Exp $ */ > > -/* $NetBSD: llrint.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ > > +/* $OpenBSD$ */ > > > > /* > > - * Written by Matthias Drochner <droch...@netbsd.org>. > > - * Public domain. > > + * Written by Martynas Venckus. Public domain > > */ > > > > -#define LRINTNAME llrint > > -#define RESTYPE long long int > > -#define RESTYPE_MIN LLONG_MIN > > -#define RESTYPE_MAX LLONG_MAX > > +#define type double > > +#define roundit rint > > +#define dtype long long > > +#define fn llrint > > > > #include "s_lrint.c" > > Index: lib/libm/src/s_llrintf.c > > =================================================================== > > RCS file: /cvs/src/lib/libm/src/s_llrintf.c,v > > retrieving revision 1.2 > > diff -u -p -r1.2 s_llrintf.c > > --- lib/libm/src/s_llrintf.c 25 Sep 2006 22:16:48 -0000 1.2 > > +++ lib/libm/src/s_llrintf.c 13 Oct 2021 23:12:11 -0000 > > @@ -1,14 +1,12 @@ > > -/* $OpenBSD: s_llrintf.c,v 1.2 2006/09/25 22:16:48 kettenis Exp $ */ > > -/* $NetBSD: llrintf.c,v 1.2 2004/10/13 15:18:32 drochner Exp $ */ > > +/* $OpenBSD$ */ > > > > /* > > - * Written by Matthias Drochner <droch...@netbsd.org>. > > - * Public domain. > > + * Written by Martynas Venckus. Public domain > > */ > > > > -#define LRINTNAME llrintf > > -#define RESTYPE long long int > > -#define RESTYPE_MIN LLONG_MIN > > -#define RESTYPE_MAX LLONG_MAX > > +#define type float > > +#define roundit rintf > > +#define dtype long long > > +#define fn llrintf > > > > #include "s_lrintf.c" > > Index: lib/libm/src/s_lrint.c > > =================================================================== > > RCS file: /cvs/src/lib/libm/src/s_lrint.c,v > > retrieving revision 1.11 > > diff -u -p -r1.11 s_lrint.c > > --- lib/libm/src/s_lrint.c 12 Sep 2016 19:47:02 -0000 1.11 > > +++ lib/libm/src/s_lrint.c 13 Oct 2021 23:12:11 -0000 > > @@ -1,9 +1,8 @@ > > -/* $OpenBSD: s_lrint.c,v 1.11 2016/09/12 19:47:02 guenther Exp $ */ > > -/* $NetBSD: lrint.c,v 1.3 2004/10/13 15:18:32 drochner Exp $ */ > > +/* $OpenBSD$ */ > > > > /*- > > - * Copyright (c) 2004 > > - * Matthias Drochner. All rights reserved. > > + * Copyright (c) 2005 David Schultz <d...@freebsd.org> > > + * All rights reserved. > > * > > * Redistribution and use in source and binary forms, with or without > > * modification, are permitted provided that the following conditions > > @@ -27,75 +26,35 @@ > > * SUCH DAMAGE. > > */ > > > > -#include <sys/types.h> > > -#include <sys/limits.h> > > -#include <float.h> > > +#include <fenv.h> > > #include <math.h> > > -#include <ieeefp.h> > > -#include <machine/ieee.h> > > > > -#include "math_private.h" > > - > > -#ifndef LRINTNAME > > -#define LRINTNAME lrint > > -#define RESTYPE long int > > -#define RESTYPE_MIN LONG_MIN > > -#define RESTYPE_MAX LONG_MAX > > +#ifndef type > > +#define type double > > +#define roundit rint > > +#define dtype long > > +#define fn lrint > > #endif > > > > -#define RESTYPE_BITS (sizeof(RESTYPE) * 8) > > - > > -static const double > > -TWO52[2]={ > > - 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ > > - -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ > > -}; > > - > > -RESTYPE > > -LRINTNAME(double x) > > +/* > > + * C99 says we should not raise a spurious inexact exception when an > > + * invalid exception is raised. Unfortunately, the set of inputs > > + * that overflows depends on the rounding mode when 'dtype' has more > > + * significant bits than 'type'. Hence, we bend over backwards for the > > + * sake of correctness; an MD implementation could be more efficient. > > + */ > > +dtype > > +fn(type x) > > { > > - u_int32_t i0, i1; > > - int e, s, shift; > > - RESTYPE res; > > - > > - GET_HIGH_WORD(i0, x); > > - e = i0 >> DBL_FRACHBITS; > > - s = e >> DBL_EXPBITS; > > - e = (e & 0x7ff) - DBL_EXP_BIAS; > > - > > - /* 1.0 x 2^31 (or 2^63) is already too large */ > > - if (e >= (int)RESTYPE_BITS - 1) > > - return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ > > - > > - /* >= 2^52 is already an exact integer */ > > - if (e < DBL_FRACBITS) { > > - volatile double t = x; /* clip extra precision */ > > - /* round, using current direction */ > > - t += TWO52[s]; > > - t -= TWO52[s]; > > - x = t; > > - } > > - > > - EXTRACT_WORDS(i0, i1, x); > > - e = ((i0 >> DBL_FRACHBITS) & 0x7ff) - DBL_EXP_BIAS; > > - i0 &= 0xfffff; > > - i0 |= (1 << DBL_FRACHBITS); > > - > > - if (e < 0) > > - return (0); > > - > > - shift = e - DBL_FRACBITS; > > - if (shift >=0) > > - res = (shift < RESTYPE_BITS ? (RESTYPE)i1 << shift : 0); > > - else > > - res = (shift > -RESTYPE_BITS ? (RESTYPE)i1 >> -shift : 0); > > - shift += 32; > > - if (shift >=0) > > - res |= (shift < RESTYPE_BITS ? (RESTYPE)i0 << shift : 0); > > - else > > - res |= (shift > -RESTYPE_BITS ? (RESTYPE)i0 >> -shift : 0); > > + fenv_t env; > > + dtype d; > > > > - return (s ? -res : res); > > + feholdexcept(&env); > > + d = (dtype)roundit(x); > > + if (fetestexcept(FE_INVALID)) > > + feclearexcept(FE_INEXACT); > > + feupdateenv(&env); > > + return (d); > > } > > -DEF_STD(LRINTNAME); > > -LDBL_MAYBE_CLONE(LRINTNAME); > > +DEF_STD(fn); > > +LDBL_MAYBE_CLONE(fn); > > Index: lib/libm/src/s_lrintf.c > > =================================================================== > > RCS file: /cvs/src/lib/libm/src/s_lrintf.c,v > > retrieving revision 1.6 > > diff -u -p -r1.6 s_lrintf.c > > --- lib/libm/src/s_lrintf.c 12 Sep 2016 19:47:02 -0000 1.6 > > +++ lib/libm/src/s_lrintf.c 13 Oct 2021 23:12:11 -0000 > > @@ -1,9 +1,8 @@ > > -/* $OpenBSD: s_lrintf.c,v 1.6 2016/09/12 19:47:02 guenther Exp $ */ > > -/* $NetBSD: lrintf.c,v 1.3 2004/10/13 15:18:32 drochner Exp $ */ > > +/* $OpenBSD$ */ > > > > /*- > > - * Copyright (c) 2004 > > - * Matthias Drochner. All rights reserved. > > + * Copyright (c) 2005 David Schultz <d...@freebsd.org> > > + * All rights reserved. > > * > > * Redistribution and use in source and binary forms, with or without > > * modification, are permitted provided that the following conditions > > @@ -27,67 +26,34 @@ > > * SUCH DAMAGE. > > */ > > > > -#include <sys/types.h> > > -#include <sys/limits.h> > > +#include <fenv.h> > > #include <math.h> > > -#include <ieeefp.h> > > -#include <machine/ieee.h> > > -#include "math_private.h" > > > > -#ifndef LRINTNAME > > -#define LRINTNAME lrintf > > -#define RESTYPE long int > > -#define RESTYPE_MIN LONG_MIN > > -#define RESTYPE_MAX LONG_MAX > > +#ifndef type > > +#define type float > > +#define roundit rintf > > +#define dtype long > > +#define fn lrintf > > #endif > > > > -#define RESTYPE_BITS (sizeof(RESTYPE) * 8) > > - > > -static const float > > -TWO23[2]={ > > - 8.3886080000e+06, /* 0x4b000000 */ > > - -8.3886080000e+06, /* 0xcb000000 */ > > -}; > > - > > -RESTYPE > > -LRINTNAME(float x) > > +/* > > + * C99 says we should not raise a spurious inexact exception when an > > + * invalid exception is raised. Unfortunately, the set of inputs > > + * that overflows depends on the rounding mode when 'dtype' has more > > + * significant bits than 'type'. Hence, we bend over backwards for the > > + * sake of correctness; an MD implementation could be more efficient. > > + */ > > +dtype > > +fn(type x) > > { > > - u_int32_t i0; > > - int e, s, shift; > > - RESTYPE res; > > - > > - GET_FLOAT_WORD(i0, x); > > - e = i0 >> SNG_FRACBITS; > > - s = e >> SNG_EXPBITS; > > - e = (e & 0xff) - SNG_EXP_BIAS; > > - > > - /* 1.0 x 2^31 (or 2^63) is already too large */ > > - if (e >= (int)RESTYPE_BITS - 1) > > - return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ > > - > > - /* >= 2^23 is already an exact integer */ > > - if (e < SNG_FRACBITS) { > > - volatile float t = x; /* clip extra precision */ > > - /* round, using current direction */ > > - t += TWO23[s]; > > - t -= TWO23[s]; > > - x = t; > > - } > > - > > - GET_FLOAT_WORD(i0, x); > > - e = ((i0 >> SNG_FRACBITS) & 0xff) - SNG_EXP_BIAS; > > - i0 &= 0x7fffff; > > - i0 |= (1 << SNG_FRACBITS); > > - > > - if (e < 0) > > - return (0); > > - > > - shift = e - SNG_FRACBITS; > > - if (shift >=0) > > - res = (shift < RESTYPE_BITS ? (RESTYPE)i0 << shift : 0); > > - else > > - res = (shift > -RESTYPE_BITS ? (RESTYPE)i0 >> -shift : 0); > > + fenv_t env; > > + dtype d; > > > > - return (s ? -res : res); > > + feholdexcept(&env); > > + d = (dtype)roundit(x); > > + if (fetestexcept(FE_INVALID)) > > + feclearexcept(FE_INEXACT); > > + feupdateenv(&env); > > + return (d); > > } > > -DEF_STD(LRINTNAME); > > +DEF_STD(fn); > > Index: lib/libm/src/s_lrintl.c > > =================================================================== > > RCS file: /cvs/src/lib/libm/src/s_lrintl.c,v > > retrieving revision 1.3 > > diff -u -p -r1.3 s_lrintl.c > > --- lib/libm/src/s_lrintl.c 15 Mar 2019 05:42:38 -0000 1.3 > > +++ lib/libm/src/s_lrintl.c 13 Oct 2021 23:12:11 -0000 > > @@ -31,9 +31,9 @@ > > > > #ifndef type > > #define type long double > > -#define roundit rintl > > +#define roundit rintl > > #define dtype long > > -#define fn lrintl > > +#define fn lrintl > > #endif > > > > /* >