Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!twinsun.com!eggert From: eggert@twinsun.com (Paul Eggert) Newsgroups: gnu.gcc.bug Subject: GCC 1.36 sometimes misconverts large unsigned integers to float Message-ID: <8912080219.AA01288@rise.twinsun.com> Date: 8 Dec 89 02:19:07 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 71 GCC 1.36 sometimes mishandles the conversion of unsigned values greater than INT_MAX to floating point. For example, the program #include 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