This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][4.3] Expand lround inline for x86_64/i?86 SSE math
On Wed, 18 Oct 2006, Geert Bosch wrote:
>
> On Oct 18, 2006, at 10:13, Richard Guenther wrote:
>
> >
> > The second patch in the series adds the expander for lround. Nothing
> > spectacular this time.
> >
> > (For reference, we expand lround to
> > movsd .LC3(%rip), %xmm2
> > movapd %xmm0, %xmm3
> > movsd .LC5(%rip), %xmm1
> > andpd %xmm2, %xmm3
> > movapd %xmm3, %xmm2
> > orpd %xmm1, %xmm2
> > movapd %xmm2, %xmm1
> > addsd %xmm0, %xmm1
> > cvttsd2siq %xmm1, %rax
> > ret
> > with .LC3 a sign mask and .LC5 being 0.5)
> >
> > Bootstrapped and tested on {x86_64,i686}-unknown-linux-gnu.
>
> Considering positive number only for the moment, do I
> understand correctly that you add 0.5 and then truncate?
> If so, that is likely incorrect for the predecessor of 0.5
> and for all odd floating-point integers with the binary
> point directly following the mantissa.
In C code the above implements
tmp = op1 + copysign (0.5, op1)
return (long)tmp;
to do lround (op1).
> If you add 0.5 to the predecessor of 0.5, the mathematical
> result will exactly between 1.0 and its predecessor and
> be rounded to nearest even, which is 1.0. Similarly
> for
>
> Two numbers to test are (for double precision):
> 0.499999999999999944488848768742172978818416595458984375
> 4503599627370497.0
>
> They should be rounded to 0.0 and 4503599627370497.0, but
> simply adding 0.5 and truncating will round to 1.0 and
> 4503599627370498.
Hm, I did test +-0, 0.5, 1.0, 1.5 with +- DBL_EPSILON added,
but that's obviously something different. Is there a way to
easily get the predecessor/successor without bit-munging the
FP representation?
I wonder if fortran specifies round differently, as the frontend
explicitly converts NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)).
Richard.
--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs