PDA

View Full Version : compiler bug: long long -> float



maxwells_daemon
01-14-2005, 07:04 PM
Just in case this bites anyone else (and in the, probably forlorn, hope that someone might have a fix), I thought it worth mentioning a bug I have found in the S1 PowerPC compiler (gcc 2.8.1). It seems that the results of converting a "long long" (64-bit integer) to a float (32-bit real) gives bad results, eg.


#include <stdio.h>
int main()
{
long long x;
float y;
x= 100;
y= x;
printf ("%lld (%u) -> %g (%u)\n", x, sizeof (x), y, sizeof (y));
return 0;
}


TiVo ~ > gcc -o x x.c -msoft-float -Wall
TiVo ~ > ./x
100 (8) -> 2148 (4)
compared to the same code built on a i686 Linux box:-

100 (8) -> 100 (4)
In contrast, all the other conversions I have tried seem to work fine (eg. long long -> double, float -> long long, etc), though I have not done an exhaustive test.

I see this with both the native and Linux cross-compiler from tivoutils.sourceforge.net, as well as my own Cygwin cross-compiler. Those are all gcc 2.8.1, built from the official TiVo toolchain, I think. I failed in my attempts to build a cross-compiler based on a later version of gcc, so I can't see whether this is specific to gcc 2.8.1.

I found this trouble when building the latest version of pstools (top was showing crazy CPU percentages). Fortunately, it's easy to work round the problem there by using double instead of float.

Tim.

dgi
02-11-2005, 02:21 PM
Notice that everything becomes OK if you simply change the line to say:
y= (double)x;If you insist on using float instead of double, do things that way until someone can figure out where gcc is going wrong. I was unable to define a 128-bit floating point variable in gcc, even though PowerPC supports that natively. The old Apple compilers used the "double double" type for that.

maxwells_daemon
02-15-2005, 02:49 PM
Thanks, that might make a simpler fix.

However the problem isn't so much an insistence on using float, but that it's often difficult to spot this sort of problem, especially in ported code. There's no compiler or run-time warning, just the wrong answer. And I imagine it won't be easy to find the problem even if you know to check for it, without carefully hand-checking the code, since float and long long are OK on their own.

I wonder whether it would be possible to make gcc give an error when it has to generate a direct float -> long long conversion? Do you know how to do that? That would make porting code safer.



I was unable to define a 128-bit floating point variable in gcc, even though PowerPC supports that natively.


Sorry, I don't understand this. I thought that the PowerPC on the TiVo didn't support floating point at all, so one had to enable software emulation (with -msoft-float, which I have as default in my cross-compiler).

Thanks,
Tim.