Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!MIST.CS.ORST.EDU!seeversb From: seeversb@MIST.CS.ORST.EDU (Bradley Seevers) Newsgroups: gnu.gcc.bug Subject: gcc bug Message-ID: <9002100153.AA07486@mist.CS.ORST.EDU> Date: 10 Feb 90 01:53:38 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 120 While using gcc 1.35 on a Sequent Balance 2100 ,(ns32k machine), I uncovered a bug with assigning constants to global varialbles of type float. At first I thought that switching over to gcc 1.36 would solve my problems. I ftp'd gcc 1.36 from prep.ai.mit.edu and rebuilt the compiler. To my suprise, the bug was virtualy identical. As an example, consider the following short program: # include float a; main() { float x; a = 3.0; x = 3.0; printf("%f\n",a); } This program produced the following assembly output when compiled with the -O -S flags and gcc v 1.35: #NO_APP gcc_compiled.: .text .align 0 LC0: .ascii "%f %f\12\0" .align 1 .globl _main _main: enter [],0 movd 416652,_a movfl 0f3.00000000000000000000e+00,tos movfl _a,tos addr LC0,tos bsr _printf adjspb -20 exit [] ret 0 .comm _a,4 The line "movd 416652,_a" is incorrect. This is not the correct value for a single precision 3.0. Note that is does ok for the local variable x. Compiling the same program with gcc v 1.36 and flags -O -S produces this output: #NO_APP gcc_compiled.: .text LC0: .ascii "%f %f\12\0" .align 1 .globl _main _main: enter [],0 movd 0,_a movfl 0f3.00000000000000000000e+00,tos movfl _a,tos addr LC0,tos bsr _printf adjspb -20 exit [] ret 0 .comm _a,4 Agin, the line "movd 0,_a" is incorrect. This bug only appears when optimization is enabled (-O). So I set about to solve this problem, after all, I had the source. The problem seems to be that all floating point constants are represented as double precision numbers, and when they are assigned to a global varialble of type float, they are not converted to single precision first. To fix this, I modified the file 'ns32k.md', changeing lines 246 - to: else if (GET_CODE (operands[1]) == CONST_DOUBLE) { union {int i[2]; float f; double d;} convrt; convrt.i[0] = CONST_DOUBLE_LOW (operands[1]); convrt.i[1] = CONST_DOUBLE_HIGH (operands[1]); convrt.f = convrt.d; /* Is there a better machine-independent way to to this? */ operands[1] = gen_rtx (CONST_INT, VOIDmode, convrt.i[0]); return \"movd %1,%0\"; } Now the example c program generates the code: #NO_APP gcc_compiled.: .text LC0: .ascii "%f %f\12\0" .align 1 .globl _main _main: enter [],0 movd 1077936128,_a movfl 0f3.00000000000000000000e+00,tos movfl _a,tos addr LC0,tos bsr _printf adjspb -20 exit [] ret 0 .comm _a,4 This code produced the correct result. -brad (seeversb@mist.cs.orst.edu)