This is the mail archive of the
libc-ports@sources.redhat.com
mailing list for the libc-ports project.
Re: [PATCH] [BZ #2749] soft-fp fixes
- From: Steven Munroe <munroesj at us dot ibm dot com>
- To: Jakub Jelinek <jakub at redhat dot com>, Joe Kerian <jkerian at linux dot ibm dot com>
- Cc: Ulrich Drepper <drepper at redhat dot com>, libc-alpha at sources dot redhat dot com, "Joseph S. Myers" <joseph at codesourcery dot com>, libc-ports at sources dot redhat dot com
- Date: Thu, 11 Jan 2007 16:22:04 -0600
- Subject: Re: [PATCH] [BZ #2749] soft-fp fixes
- Organization: IBM LTC
- References: <452E65FE.3030808@us.ibm.com> <20070110154925.GY3819@sunsite.mff.cuni.cz>
Jakub Jelinek wrote:
>On Thu, Oct 12, 2006 at 10:57:50AM -0500, Steven Munroe wrote:
>
>>2006-10-05 Steven Munroe <sjmunroe@us.ibm.com>
>> Joe Kerian <jkerian@us.us.ibm.com>
>>
>> [BZ #2749]
>> * soft-fp/fenv_libc.h: New file.
>>
>
>Top level soft-fp directory doesn't sound like a good place for this,
>it has nothing to common with fenv_libc.h. IMHO either stick it into
>math/fenv_libc.h, or let just each port provide its own (all current
>in tree arches that ever use fenv_libc.h do that, so ppc no-fpu could
>do the same).
>
>
Ok, Moved fenv_libc.h to sysdeps/powerpc/nofpu.
>> (_FP_PACK_SEMIRAW): Update comment. Do not round if NaN.
>>
>
>
>>--- libc25-cvstip-20061005/soft-fp/op-common.h 2006-04-04 03:24:47.000000000 -0500
>>+++ libc24/soft-fp/op-common.h 2006-10-10 09:45:04.000000000 -0500
>>@@ -131,10 +131,12 @@
>>
>> /* Prepare to pack an fp value in semi-raw mode: the mantissa is
>> rounded and shifted right, with the rounding possibly increasing
>>- the exponent (including changing a finite value to infinity). */
>>+ the exponent (including changing a finite value to infinity).
>>+ Be sure not to round NaNs. */
>> #define _FP_PACK_SEMIRAW(fs, wc, X) \
>> do { \
>>- _FP_ROUND(wc, X); \
>>+ if(X##_e != _FP_EXPMAX_##fs) \
>>+ _FP_ROUND(wc, X); \
>> if (_FP_FRAC_HIGH_##fs(X) \
>> & (_FP_OVERFLOW_##fs >> 1)) \
>> { \
>>
>
>Can you please explain where does this make a difference?
>NaNs should have the least significant 3 bits (_FP_WORKBITS) cleared
>since they were shifted up during unpacking, so even when _FP_ROUND is
>called on the NaN, it shouldn't affect it in any way (_FP_ROUND does
>nothing if the work bits are all 0).
>
>
This pops up for operations like:
/* take care of Inf and NaN */
if((ix&0x7f800000)==0x7f800000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf,
sqrt(-inf)=sNaN */
this will happen for sqrtf(-inf) for example but instead of a NaN we get
0.0. and results in 14 detected errors in test-float.
While the fraction is zero for -inf , the test in _FP_ROUND_NEAREST is
#define _FP_ROUND_NEAREST(wc, X) \
do { \
if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \
_FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
} while (0)
so even if the guard bits are zero going in (0b0000 != 0b0100) , the
_FP_FRAC_ADDI_ occurs. These causes problems for float because
_FP_FRAC_LOW_ and _FP_FRAC_HIGH_ are the sameword. I have not verified
this but I suspect this cases the exponent to be incremented past
_FP_EXPMAX_ , The final _FP_PACK_RAW_1 results in a zeros in the
exponent and mantisa.