[gnu.gcc.bug] bug in sparc gcc 1.35

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (05/04/89)

GCC produces bad assembly when compiling the following code with "-O
-fforce-mem". This is on a Sun4/110 running SunOs 4.0.  The test for
the while loop is performed incorrectly, usually causing an infinite
loop.

The compile:
gcc -g -v -S -O -fforce-mem   -c make-docfile.c -o make-docfile.o
gcc version 1.35
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ make-docfile.c /tmp/cca07848.cpp
GNU CPP version 1.35
 /usr/local/lib/gcc-cc1 /tmp/cca07848.cpp -quiet -dumpbase make-docfile.c -fforce-mem -g -O -version -o make-docfile.o
GNU C version 1.35 (sparc) compiled by GNU C version 1.35.

The bad assembly:
.stabn 68,0,106,LM73
LM73:
	mov %l2,%o0
	call _read_c_string,0
	mov 1,%o1
L4:
	andcc %l6,16,%g0    ! l6 is not even mentioned before this.
			    ! This should be "ldsh [%l2+16] %l6; andcc ..."
	be L97
	nop

The code:
------------------------------------------------------------------------
extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		 
} _iob[];
extern struct _iobuf 	*fopen();
struct _iobuf  *outfile;
char buf[128];
scan_c_file (filename)
     char *filename;
{
  struct _iobuf  *infile;
  register int c;
  register int commas;
  register int defunflag;
  register int defvarflag;
  if (filename[strlen (filename) - 1] == 'o')
    filename[strlen (filename) - 1] = 'c';
  infile = fopen (filename, "r");
  if (infile == 0 )
    {
      perror (filename);
      return 0;
    }
  c = '\n';
  while (!	(((infile)->_flag&020 )!=0) )
    {
      if (c != '\n')
	{
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  continue;
	}
      c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
      if (c == ' ')
	{
	  while (c == ' ')
	    c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  if (c != 'D')
	    continue;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  if (c != 'E')
	    continue;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  if (c != 'F')
	    continue;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  if (c != 'V')
	    continue;
	  defvarflag = 1;
	  defunflag = 0;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	}
      else if (c == 'D')
	{
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  if (c != 'E')
	    continue;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  if (c != 'F')
	    continue;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	  defunflag = c == 'U';
	  defvarflag = 0;
	}
      else continue;
      while (c != '(')
	{
	  if (c < 0)
	    return 0;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	}
      c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
      if (c != '"')
	continue;
      c = read_c_string (infile, -1);
      if (defunflag)
	commas = 5;
      else if (defvarflag)
	commas = 1;
      else   
	commas = 2;
      while (commas)
	{
	  if (c == ',') commas --;
	  if (c < 0)
	    return 0;
	  c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
	}
      while (c == ' ' || c == '\n' || c == '\t')
	c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
      if (c == '"')
	c = read_c_string (infile, 0);
      while (c != ',')
	c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
      c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
      while (c == ' ' || c == '\n' || c == '\t')
	c = 	(--(infile)->_cnt>=0? ((int)*(infile)->_ptr++):_filbuf(infile)) ;
      if (c == '"')
	{
	  (--( outfile)->_cnt >= 0 ?	(int)(*( outfile)->_ptr++ = (unsigned char)(037)) :	((( outfile)->_flag & 0200 ) && -( outfile)->_cnt < ( outfile)->_bufsiz ?	((*( outfile)->_ptr = (unsigned char)(037)) != '\n' ?	(int)(*( outfile)->_ptr++) :	_flsbuf(*(unsigned char *)( outfile)->_ptr,  outfile)) :	_flsbuf((unsigned char)(037),  outfile))) ;
	  (--( outfile)->_cnt >= 0 ?	(int)(*( outfile)->_ptr++ = (unsigned char)(defvarflag ? 'V' : 'F')) :	((( outfile)->_flag & 0200 ) && -( outfile)->_cnt < ( outfile)->_bufsiz ?	((*( outfile)->_ptr = (unsigned char)(defvarflag ? 'V' : 'F')) != '\n' ?	(int)(*( outfile)->_ptr++) :	_flsbuf(*(unsigned char *)( outfile)->_ptr,  outfile)) :	_flsbuf((unsigned char)(defvarflag ? 'V' : 'F'),  outfile))) ;
	  fprintf (outfile, "%s\n", buf);
	  read_c_string (infile, 1);
	}
    }
  fclose (infile);
  return 0;
}

zjat02@cra2.uucp (Jon A. Tankersley) (05/11/89)

Something trashed my tm-sparc.h sometime between 1.34 and 1.35.
Could someone email me a copy?
-tank-
#include <std/disclaimer.h>		/* nobody knows the trouble I .... */
tank@apctrc.trc.amoco.com    ..!uunet!apctrc!tank

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (05/31/89)

The following code will cause gcc to abort when compiled with the "-O
-fstrength-reduce" flags.  This is gcc version 1.35 with a fix to
optabs.c on a Sun4/110 running SunOS 4.0.

Tom Quinn                 Canadian Institute for Theoretical Astrophysics
trq@moose.cita.utoronto.ca
UUCP   - decvax!utgpu!moose!trq
BITNET - quinn@utorphys.bitnet
ARPA   - trq%moose.cita.toronto.edu@relay.cs.net

The compile:
make stats.o CFLAGS="-g -v -O -fstrength-reduce"
gcc -g -v -O -fstrength-reduce   -c stats.c -o stats.o
gcc version 1.35
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ stats.c /tmp/cca13385.cpp
GNU CPP version 1.35
 /usr/local/lib/gcc-cc1 /tmp/cca13385.cpp -quiet -dumpbase stats.c -fstrength-reduce -g -O -version -o /tmp/cca13385.s
GNU C version 1.35 (sparc) compiled by GNU C version 1.35.
gcc: Program cc1 got fatal signal 6.

The code:
------------------------------------------------------------------------
typedef	unsigned int	u_int;
union word {  
	u_int size;			 
	union word *next;	 
	union word *prev;	 
	char *donothing;	 
	long foo[2] ;				 
};
typedef union word Word;
extern int _malloc_scount[];
malloc_dumpstats(fd)
int fd;
{
	int i;
	char buf[128];
	for (i = 1; i < 2*1024 ; i++) {
		if(_malloc_scount[i] > 0) {
			(void) sprintf(buf, "%d: %d\n", i * sizeof(Word),
			 _malloc_scount[i]);
			(void) write(fd, buf, strlen(buf));
			_malloc_scount[i] = 0;
		}
	}
	if (_malloc_scount[0] > 0) {
		(void) sprintf(buf, ">= %d: %d\n", 2*1024  * sizeof(Word), 
		 _malloc_scount[0]);
		(void) write(fd, buf, strlen(buf));
		_malloc_scount[0] = 0;
	}
}