Article View: gnu.gcc.bug
Article #2867gcc bug
From: Bradley Seevers
Date: Sat, 10 Feb 1990 01:53
Date: Sat, 10 Feb 1990 01:53
120 lines
3031 bytes
3031 bytes
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 <stdio.h>
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)
Technical Details
Message-ID:
<9002100153.AA07486@mist.CS.ORST.EDU>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!MIST.CS.ORST.EDU!seeversbShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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