[gnu.gcc.bug] GCC 1.36 -O

eggert@twinsun.com (Paul Eggert) (11/10/89)

The following C program should print 0.  Under GCC 1.36 on a Sparcstation 1
(SunOS 4.0.3) using the -O option, it prints 7.

	#include <stdio.h>

	double d;

	main(argc, argv)
		int argc;
		char **argv;
	{
		if (argc) {
			union { float f; long l;} t;
			t.f = d;
			fprintf(stdout, "%d\n", t.l);
		} else
			fprintf(stdout, "");
		return 0;
	}

Here is a transcript.

	1-rise% gcc -v -O a.c
	gcc version 1.36
	 /local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ a.c /usr/tmp/cca17592.cpp
	GNU CPP version 1.36
	 /local/lib/gcc-cc1 /usr/tmp/cca17592.cpp -quiet -dumpbase a.c -O -version -o /usr/tmp/cca17592.s
	GNU C version 1.36 (sparc) compiled by GNU C version 1.36.
	default target switches: -mfpu -mepilogue
	 as -o a.o /usr/tmp/cca17592.s
	 ld -e start -dc -dp /lib/crt0.o a.o /local/lib/gcc-gnulib -lc
	2-rise% ./a.out
	7

Here is the assembly language output.  I am not a Sparc expert, but the
code marked **** looks like GCC tried to shoehorn two instructions into
one delay slot.

gcc_compiled.:
.text
LC0:
	.ascii "%d\12\0"
LC1:
	.ascii "\0"
	.align 4
.global _main
	.proc 1
_main:
	!#PROLOGUE# 0
	save %sp,-112,%sp
	!#PROLOGUE# 1
	tst %i0
	be L2
	nop
	sethi %hi(_d),%g1
	ldd [%g1+%lo(_d)],%f2
	fdtos %f2,%f2
	sethi %hi(__iob),%o0
	or %lo(__iob),%o0,%o0
	add %o0,20,%o0
	sethi %hi(LC0),%o1
	or %lo(LC0),%o1,%o1
	b L4
	st %f2,[%fp-4]			****
	ld [%fp-4],%o2			****
L2:
	sethi %hi(__iob),%o0
	or %lo(__iob),%o0,%o0
	add %o0,20,%o0
	sethi %hi(LC1),%o1
	or %lo(LC1),%o1,%o1
L4:
	call _fprintf,0
	nop
	mov 0,%i0
	ret
	restore
.global _d
.common _d,8,"bss"