[gnu.gcc.bug] GCC 1.36 sometimes misconverts large unsigned integers to float

eggert@twinsun.com (Paul Eggert) (12/08/89)

GCC 1.36 sometimes mishandles the conversion of unsigned values greater than
INT_MAX to floating point.  For example, the program

	#include <stdio.h>

	main()
	{
		unsigned long L;
		double D;
		D = L = ~0;
		printf("L=%lu, D=%g\n", L, D);
		return 0;
	}

should print something like "L=4294967295, D=4.29497e+09".  Instead, D has
either the value 0 (Sun-3 -m68881, or Sun-4) or -1 (Sun-3 -msoft-float).
Looking at the generated code, there seem to be two different bugs depending
on whether -msoft-float is set.  The 0 arises when GCC converts unsigned long
as if it were long, notices that the original number was negative, and
corrects by adding 1; it should correct by adding 4294967296.  The -1 arises
because GCC uses __floatsidf to convert the unsigned long to double;
__floatsidf expects a signed long argument.

In the following transcripts, 'dry' is a Sun-3/60 running SunOS 4.0.3; 'rise'
is a SPARCstation 1 running SunOS 4.0.3c.

1-dry% gcc -v -m68881 t.c
gcc version 1.36
 /local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D
__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 t.c /usr/tmp/cca20148.cpp
GNU CPP version 1.36
 /local/lib/gcc-cc1 /usr/tmp/cca20148.cpp -quiet -dumpbase t.c -m68881 -version
-o /usr/tmp/cca20148.s
GNU C version 1.36 (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -mbitfield
 as -mc68020 -o t.o /usr/tmp/cca20148.s
 /local/lib/gcc-ld -e start -dc -dp /lib/crt0.o /lib/Mcrt1.o t.o /local/lib/gcc-
gnulib -lc
2-dry% ./a.out
L=4294967295, D=0


3-dry% gcc -v -msoft-float t.c
gcc version 1.36
 /local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D
__sun__ -D__unix__ -Dmc68020 t.c /usr/tmp/cca20154.cpp
GNU CPP version 1.36
 /local/lib/gcc-cc1 /usr/tmp/cca20154.cpp -quiet -dumpbase t.c -msoft-float -ver
sion -o /usr/tmp/cca20154.s
GNU C version 1.36 (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -mbitfield
 as -mc68020 -o t.o /usr/tmp/cca20154.s
 /local/lib/gcc-ld -e start -dc -dp /lib/crt0.o /lib/Fcrt1.o t.o /local/lib/gcc-
gnulib -lc
4-dry% ./a.out
L=4294967295, D=-1


1-rise% gcc -v t.c
gcc version 1.36
 /local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__su
n__ -D__unix__ t.c /usr/tmp/cca01280.cpp
GNU CPP version 1.36
 /local/lib/gcc-cc1 /usr/tmp/cca01280.cpp -quiet -dumpbase t.c -version -o /usr/
tmp/cca01280.s
GNU C version 1.36 (sparc) compiled by GNU C version 1.36.
default target switches: -mfpu -mepilogue
 as -o t.o /usr/tmp/cca01280.s
 /local/lib/gcc-ld -e start -dc -dp /lib/crt0.o t.o /local/lib/gcc-gnulib -lc
2-rise% ./a.out
L=4294967295, D=0