Bug 51072 - incorrect underflow behavior for double functions in libm
Summary: incorrect underflow behavior for double functions in libm
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: glibc
Version: 7.1
Hardware: alpha
OS: Linux
medium
high
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Aaron Brown
URL: ftp://ftp.cita.utoronto.ca/pub/vanhoo...
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2001-08-07 01:08 UTC by Peter van Hoof
Modified: 2016-11-24 14:55 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2003-04-22 02:12:54 UTC
Embargoed:


Attachments (Terms of Use)
bug3.c: sample program that triggers the bug (664 bytes, text/plain)
2001-08-07 01:11 UTC, Peter van Hoof
no flags Details

Description Peter van Hoof 2001-08-07 01:08:03 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.76 [en] (X11; U; SunOS 5.8 sun4m)

Description of problem:
math library functions for double precision arguments can produce subnormal
numbers
even when -mieee is not specified. when these are passed on to the
hardware, they
cause a crash on a floating exception

How reproducible:
Always

Steps to Reproduce:
1. gcc bug3.c -lm
2. a.out
3.
	

Actual Results:  result 1a: 1.175494e-38 -8.733655e+01
result 1b: 0.000000e+00
result 1c: 0.000000e+00
result 2a: 2.225074e-308 -7.083964e+02
result 2b: 1.349576e-308
Floating exception


Expected Results:  result 1a: 1.175494e-38 -8.733655e+01
result 1b: 0.000000e+00
result 1c: 0.000000e+00
result 2a: 2.225074e-308 -7.083964e+02
result 2b: 0.000000e+00
result 2c: 0.000000e+00
result 3a: 2.225074e-308 -7.083964e+02
result 3b: 0.000000e+00
result 3c: 0.000000e+00


Additional info:

the math library behaves correctly for single precision arguments, the bug
is only
triggered when double precision arguments are passed. long doubles are
treated
the same as doubles by gcc on this machine and may be ignored.

result 2a shows DBL_MIN and the natural logarithm of that number

result 2b in the Actual Results shows a subnormal number:
exp(log(DBL_MIN)-0.5),
it should have underflowed to zero, as is shown in the Expected Results
(which
were obtained using ccc instead of gcc on the same computer).

The subnormal number is passed on to the hardware to be multiplied by 2,
which
causes the Floating exception.

bug3.c can be obtained from the URL listed above, and will be attached to
this
report as well.

Comment 1 Peter van Hoof 2001-08-07 01:11:33 UTC
Created attachment 26538 [details]
bug3.c: sample program that triggers the bug

Comment 2 Jakub Jelinek 2001-08-07 13:40:45 UTC
There is just one libm, not a separate one for non-mieee and -mieee.
The reason why your program does not fail for float is that you don't call
logf or expf but log resp. exp, so the caller has to convert them to float
from double and thus flush to zero happens.
I think it is a bug in the program if you are doing something which results
in subnormal numbers and are not compiling with -mieee (the whole distribution
uses this flag on alpha), at least I don't think it is worthy to have 2 different
libm libraries and multilib them (and there is obviously a need for libm
which gives precise results).
I'll let Richard comment on this though...

Comment 3 Peter van Hoof 2001-08-07 17:17:48 UTC
Let me point out that I do not want to use subnormal number at all !

I compile without the -mieee flag because that gives more efficient code and
that is exactly what I want. I am perfectly happy to live with the resulting
abrupt
underflow. However, I find that the math library forces the subnormal numbers
onto me anyway, and then the compiler handles the results incorrectly by
passing the subnormal numbers directly to the hardware which doesn't support
them and causes the program to crash.

Whatever computing standard you support, the simple test case I supplied
should never crash. It should either result in an underflow to zero, or to a
subnormal number, but not a floating exception. I am doing nothing illegal
or inappropriate in that code.

Let me also point out that the IEEE standard is NOT intended to give more
precise results, it is intended give more standardized behaviour across various
platforms. However, on machines which do not support gradual underflow
in hardware (such as the alpha chip) that comes at a significant price in terms
of computing speed. My personal opinion is (and I am aware that I may not be
speaking for everybody here) that this kind of degradation in computing speed
should not be forced on the user.

PS - The attached program doesn't work correctly with -mieee either, but I
guess that is a separate bug....

Comment 4 Richard Henderson 2001-08-07 18:03:48 UTC
If you want denormals to underflow, I suggest you set FE_MAP_DMZ and FE_MAP_UMZ
in the floating point environment.  This can be done with
fesetenv(FE_NONIEEE_ENV).  On EV6 machines, the flush to zero is then handled in
hardware.  For earlier machines, you'll need something like this:

static inline double flush_to_zero(double x)
{
#ifndef __alpha_ev6__
  double exp;
  asm ("cpyse %2,$f31,%1; cpys %2,$f31,%0; fcmovne %1,%2,%0"
	: "=&f"(x), "=&f"(exp) : "f"(x));
#endif
  return x;
}

to be used like so 

	result = flush_to_zero(exp(x));

I agree that it would be nice if this all sort of happened automatically with
libm, but that's not likely to happen overnight, or even soon.

Oh, there's also the DEC cpml library, which in addition to havling faster
versions of some math routines, also may flush to zero by default.  See

	ftp://ftp.compaq.com/pub/products/C-CXX/linux/compaq_c

Comment 5 Peter van Hoof 2001-08-07 23:34:22 UTC
I was able to get correct behaviour of the code using fesetenv(FE_NONIEEE_ENV)
on EV56 hardware. Thanks for the work-around !

Linking the gcc code against the Compaq math library (-lcpml) also works fine.
It flushes to zero by default and is also faster than the standard math library.

However, if you have the Compaq math library, chances are that you have a
working ccc compiler as well. In that case I would advise to use ccc since it
gives faster code than gcc (at least for my program) and gives correct behaviour
by default.

Comment 6 Ulrich Drepper 2003-04-22 02:12:54 UTC
There is no point in keeping this bug open.  Red Hat will not actively work on
any Alpha issue.  And the glibc maintainers also have not much interest in doing
this work.  If you still want to see this working as you expect it you'll
probably have to come up with a patch yourself and send it to the glibc lists.


Note You need to log in before you can comment on or make changes to this bug.