Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Jan 2000 12:14:59 +0100
From:      Martin Cracauer <cracauer@cons.org>
To:        Markus Holmberg <saska@acc.umu.se>
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: Should -mieee-fp equal fpsetmask(0) to avoid SIGFPE on FreeBSD?
Message-ID:  <20000104121459.A8959@cons.org>
In-Reply-To: <20000104023648.A43673@fysgr387.sn.umu.se>; from Markus Holmberg on Tue, Jan 04, 2000 at 02:36:48AM %2B0100
References:  <20000104023648.A43673@fysgr387.sn.umu.se>

next in thread | previous in thread | raw e-mail | index | archive | help
In <20000104023648.A43673@fysgr387.sn.umu.se>, Markus Holmberg wrote: 
> The direct reason for me asking about this is a FreeBSD-specific bug in
> Mozilla (that needs help from someone who knows this):
> 
> http://bugzilla.mozilla.org/show_bug.cgi?id=9967

This specific example shows why it is sometimes good to have
exceptions enabled.

The problem in the Mozilla source is that a floating point number that
is bigger than MAX_INT is converted to an int. Not a value that is
theoretically bigger, the trap happens only when it actually is
bigger, and it does in practice.

This causes an FPU exception. Not an "overflow" like a normal floating
point operation would, but an "invalid operation".

Why's that? The normal (float -> float values) "overflow" exception
signals that an overflow happened that otherwise would be handled fine
by setting the result value to "infinity". If you disabled the
exception, the code would be able to work, the result is a value that
is correct in its semantics. because floating point numbers have
special values for infinity and such. Integers don't.

In the integer case (converting a float value > MAX_INT to int) the
result will be undefined and in fact nonsense if you disabled the
exception.

Try it out: The integer result of such a conversion is not the integer
value is is nearest to the float value that was converted, it is
complete nonsense. Even if it was converted to INT_MAX, it would not
be useful. Absulutely unusable. 

#include <stdio.h>
#include <limits.h>
#include <floatingpoint.h>

int main(void)
{
  double bla;
  int foo;

  fpsetmask(0);
  bla = (double)INT_MAX + 1.0;
  foo = bla;

  printf("Result: %d\n", foo);

  return 0;
}

Result: -2147483648


There is no way that an application could to anything useful with an
integer value that was converted from a float > MAX_INT, because its
value is just unspecified.

Hence it is good to trap this and it is a bug in Mozilla, period.

The specific code in question may be built in a way that the result is
not used anyway (either never or not in the overflow case). In that
case (and only then), the code may work correctly. But in that case
the (costly) conversion would also be useless and should not have been
done in first place.

If you disable exceptions in programs, you should at least leave
"invalid operation" on. The "softer" traps that run into meaningful
results (overflow, division by zero etc.) may be disabled with less
care, but the specific case that causes the Mozilla trap should be
left enabled.

Similar problems exist for FPU stack errors. The i387 CPU has an
unformtunate mapping of error causes to sperately maskable exceptions,
in many cases it is better to leave them all unmasked so that no
serious error may slip through. Search for old posting of Bruce Evans
about gcc/libm bugs that may result in traps you want to catch.

I think we might discuss lowing the traps so that the softer
exceptions are disabled. But most cases where people cry about
FreeBSD's behaviour are serious errors like the one in mozilla, so we
won't gain much.

If you want to change the behaviour system-wide, change
  __INITIAL_NPXCW__ 
in 
  src/sys/i386/include/npx.h.

Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <cracauer@cons.org> http://www.cons.org/cracauer/
BSD User Group Hamburg, Germany     http://www.bsdhh.org/


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000104121459.A8959>