This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: New development branch: ia64-fp-model-branch



On Nov 4, 2004, at 21:02, Zack Weinberg wrote:
Also, it wouldn't help.  The problem with spills from the register
stack is that reload has no reason to believe that the value is not a
true SFmode or DFmode quantity, so it issues a truncating store.  (The
ia64 architecture doesn't have this problem because all arithmetic
instructions have the ability to round to single or double after the
operation, so the narrow store doesn't truncate.  Actually, adding
__fpreg, with its passive-conversion behavior, creates a situation
where the problem *can* occur on ia64 - if a float variable has a
passively-converted quantity in it, with more bits of mantissa than it
should, and it gets spilled to memory before use, those extra bits
will be lost.  However, the vast number of registers on ia64 makes
this relatively unlikely to occur in practice.)

For both systems it makes sense in my opinion to have a notion of __fpreg. It is essential that spilling/filling does not introduce *any* form of rounding or other observable behavior. That optimization levels affect results of numerical algorithms is one of the greatest failures of GCC on x86.

Even when the rounding mode for the x86 is set to round at 53 bits
of mantissa, instructions like fexp still computes a 64-bit mantissa.
This makes sense, as the additional precision makes it much easier
to design an accurate pow() function, for example. However, we need
to be able to reliably use this extra precision regardless of
current rounding mode. So, use __fpreg for this purpose.

Also, it is not acceptable to go into the "very unlikely to mess
up your answers" mode. When arbitrary extra rounding becomes very
rare, it just makes it harder to find the cause when an otherwise
perfectly fine program produces a wrong result. It will happen.

For floating-point spilling/filling, we should always use the
widest type that the register (or register-pair) can hold.
It's also a good idea to have extra flags for arithmetic
operations that specify properties such as expected rounding mode
(specific, or "default") and behavior on overflow. This would
be useful for both integer and float operations.

For x86, we would set/reset rounding modes between operations where
necessary, while for IA-64 we would mostly select the relevant control
register, only modifying it when we require a specific rounding mode
that is neither SF0 or SF1.

From what I have seen so far, and from my experience with both IA-32
and IA-64 floating-point math, it seems to me that the gaps in
GCC's handling of floating-point are similar for both architectures,
and a proper design should be able to fix both. Indeed this will
require reload hacking...

-Geert


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]