> 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
> >
> >  /*
> 

Reply via email to