Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Mon, 23 Sep 2019 12:08:18 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: [PATCH] math: optimize lrint on 32bit targets

On Mon, Sep 23, 2019 at 04:54:23PM +0200, Szabolcs Nagy wrote:
> * Rich Felker <dalias@...c.org> [2019-09-23 10:24:36 -0400]:
> > On Sun, Sep 22, 2019 at 10:43:35PM +0200, Szabolcs Nagy wrote:
> > > +long lrint(double x)
> > > +{
> > > +	uint32_t abstop = asuint64(x)>>32 & 0x7fffffff;
> > > +	uint64_t sign = asuint64(x) & (1ULL << 63);
> > > +
> > > +	if (abstop < 0x41dfffff) {
> > > +		/* |x| < 0x7ffffc00, no overflow */
> > > +		double_t toint = asdouble(asuint64(1/EPS) | sign);
> > > +		double_t y = x + toint - toint;
> > > +		return (long)y;
> > > +	}
> > > +	return lrint_slow(x);
> > > +}
> > >  #else
> > >  long lrint(double x)
> > >  {
> > > -- 
> > 
> > Looks good! Thanks for working on this.
> > 
> > Does asuint64(1/EPS) compile to an integer constant rather than
> > needing to load a floating point operand? I would assume so but just
> > want to check, since otherwise it might make more sense to write this
> > as an expression involving [L]DBL_MANT_DIG and integer bitshifts.
> 
> i think if 1/EPS was rounding mode dependent then it would
> be computed at runtime, but since it's an exact power-of-two
> gcc const folds it (on arm there is no load, the value is put
> together by bitops with immediates)

Nice. I'm checking and yes it looks fine. Looks similar (modulo bad
codegen in general) on sh4 too, chosen as another arch with hardfloat
but no optimized lrint, and where there's not really any good way to
write one -- the only conversion insn is a truncating one.

Rich

Powered by blists - more mailing lists

Your e-mail address:

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.