🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #2867

gcc bug

#2867
From: Bradley Seevers
Date: Sat, 10 Feb 1990 01:53
120 lines
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!seeversb

Show 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