------- Comment #5 from mikpe at it dot uu dot se  2010-07-15 21:30 -------
Created an attachment (id=21219)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=21219&action=view)
updated long long to double conversion test

I've updated the test case to try conversions of a larger range of values, and
to convert them back to calculate the diffs due to precision loss.

When testing this on a couple of machines I noticed that the -mcpu=v9 code
(fxtod) behaves differently depending on processor generation and OS kernel.

On a USIIIi (Sun Blade 2500 Red) with Linux kernel 2.6.35-rc5 I get:
> ./pr44631v2-v9 
0x015c181b6dc019dc -> 2.47804e+17 (0x438b83036db8033c) -> 0x0370606db7006780,
diff 149824205863538084
0x0100000000000000 -> 1.44115e+17 (0x4380000000000000) -> 0x0200000000000000,
diff 72057594037927936
0x00ffffffffffffff -> 7.20576e+16 (0x4370000000000000) -> 0x0100000000000000,
diff 1
0x0020000000000001 -> 9.00720e+15 (0x4340000000000000) -> 0x0020000000000000,
diff -1
0x0020000000000000 -> 9.00720e+15 (0x4340000000000000) -> 0x0020000000000000,
diff 0
0x001fffffffffffff -> 9.00720e+15 (0x433fffffffffffff) -> 0x001fffffffffffff,
diff 0

That is, going from 0x00ffffffffffffff to the next higher integer results in a
huge difference in the resulting double.

On a USIIi (Ultra5) with Linux kernel 2.6.35-rc5 the same binary gives:
> ./pr44631v2-v9 
0x015c181b6dc019dc -> 9.79798e+16 (0x4375c181b6dc019e) -> 0x015c181b6dc019e0,
diff 4
0x0100000000000000 -> 7.20576e+16 (0x4370000000000000) -> 0x0100000000000000,
diff 0
0x00ffffffffffffff -> 7.20576e+16 (0x4370000000000000) -> 0x0100000000000000,
diff 1
0x0020000000000001 -> 9.00720e+15 (0x4340000000000000) -> 0x0020000000000000,
diff -1
0x0020000000000000 -> 9.00720e+15 (0x4340000000000000) -> 0x0020000000000000,
diff 0
0x001fffffffffffff -> 9.00720e+15 (0x433fffffffffffff) -> 0x001fffffffffffff,
diff 0

That is, while rounding occurs there are no huge jumps in the intermediate
double representation.  In fact, the output exactly matches the output for the
-mcpu=v8 case which uses pure SW conversions instead of fxtod.

So USIIIi and USIIi behave differently.

On another USIIIi (Sun Fire V240) running Solaris 10, a gcc-4.4.4 -mcpu=v9
binary again gives the exact same results as -mcpu=v8 or USIIi runs.

So Linux and Solaris behave differently on USIIIi.

Both the Linux and Solaris kernels for SPARC contain FP emulation support for
various cases the HW doesn't like to handle.  According to comments in the
Linux kernel one of the changes in USIII from earlier generations was that
fxtod started to trap for certain cases.  According to debugging code I added
to the Linux kernel, fxtod does trap and get emulated on USIIIi for many (all?)
cases where the conversion is inexact, including the test cases where fxtod
produced very wrong values.

So it appears the Linux kernel's emulation of fxtod is broken.

My Linux kernel on the USIIIi was compiled by gcc-4.4.4.  As a final test I
recompiled it with gcc-3.4.6, but that made no difference.

So I suspect a kernel logic error, not a miscompilation.

BTW, in an interim version of the test case I did log the value of FSR, but all
three systems (Linux USIIi, Linux USIIIi, and Solaris USIIIi) did run with the
same rounding and exception control settings so that's not the issue.


-- 

mikpe at it dot uu dot se changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #20986|0                           |1
        is obsolete|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44631

Reply via email to