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

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (03/17/89)

The follwing code will compile incorrectly with the "-O -meager"
flags.  This is on a Sun4/110 running SunOs 4.0.  The compiler moves
an instruction it shouldn't in to a delay slot.

The compile:
gcc -g -v -S -O -meager   -c editor.c -o editor.o
gcc version 1.34
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ editor.c /tmp/cca04419.cpp
GNU CPP version 1.34
 /usr/local/lib/gcc-cc1 /tmp/cca04419.cpp -quiet -dumpbase editor.c -meager -g -O -version -o editor.o
GNU C version 1.34 (sparc) compiled by GNU C version 1.34.

The bad assembly:
.stabn 68,0,66,LM18
LM18:
	ldsb [%o1],%o0
	cmp %o0,42
	bne L11 ! eager
	add %o1,1,%o1		! this instruction gets executed
				! whether the branch is taken or not
L11:
.stabn 68,0,67,LM19
LM19:
	sethi %hi(LC8),%o0
	call _printf,0
	or %o0,%lo(LC8),%o0

The code:
------------------------------------------------------------------------
extern	char	_ctype_[];
struct winsize {
	unsigned short	ws_row;		 
	unsigned short	ws_col;		 
};
typedef struct {
   int dlin,			 
       ncol,			 
       nlin;			 
   char name[40 ],	 
	del_char[40 ],	 
	del_line[40 ],	 
	forw_curs[40 ],	 
   	set_keys[40 ],	 
   	unset_keys[40 ];	 
} TERMINAL;
extern TERMINAL term;			 
typedef struct {
int t_baud,			 
    t_nlines,			 
    t_ncols,			 
    t_ncaps,			 
    t_caplen,			 
    t_len,			 
    t_op,			 
    t_capcode[100],	 
    t_capindex[100];	 
char t_padchar,				 
     *t_caplist;			 
} TTY;
TERMINAL term;				 
int curs_prop,				 
    nlines;
set_term_type(term_type,nl)
char *term_type;
int nl;				 
{
   char buff[40 ],
   	*cap_file,
   	*getenv(),
        *get_val(),
   	*strncpy();
   static int first = 1;		 
   TTY *ttyopen();
   static TTY *tty;
   static int fildes = -1;
   struct winsize twinsiz;
   if(first) {
      first = 0;
      (void)define_key("^[b",'b' | '\200');
      (void)define_key("^[d",'d' | '\200');
      (void)define_key("^[f",'f' | '\200');
      (void)define_key("^[h",'h' | '\200');
      (void)define_key("^[q",17 );
      (void)define_key("^[u",'u' | '\200');
      (void)define_key("^[v",'v' | '\200');
      (void)define_key("^[y",'y' | '\200');
   }
   if(term_type == 0 ) return(-1);
   {	char *ptr = term.unset_keys;
	while(((_ctype_+1)[*ptr]&04 ) ) ptr++;
	if(*ptr == '.') {
	    ptr++;
	    while(((_ctype_+1)[*ptr]&04 ) ) ptr++;
	}
	if(*ptr == '*') ptr++;
	printf("%s",ptr);
    } ;		 
   if(!strcmp(term_type,"dumb")) {	 
      term.forw_curs[0] = '\0';
      curs_prop = 0			;
      term.del_char[0] = '\0';
      term.del_line[0] = '\0';
      term.ncol = 80;
      term.nlin = 0;
      nlines = (nl != 0) ? abs(nl) : 20;
      return(0);
   }
   if((cap_file = getenv("TERMCAP")) == 0 ) {     
      if((cap_file = get_val("termcap")) == 0 ) {  
         cap_file = "/etc/termcap";
      }
   }
   if((tty = ttyopen(cap_file,term_type,(int (*)())0 )) == 0 ) {
      return(-1);
   }
   tty_index_caps(tty,tty->t_capcode, tty->t_capindex);
   (void)ttygets(tty,"ch",term.forw_curs,40 );	 
   if(!strcmp(term.forw_curs,"disabled")) {
      term.forw_curs[0] = '\0';
   } else if(term.forw_curs[0] == '\0') {		 
      (void)ttygets(tty,"cm",term.forw_curs,40 );
      curs_prop = 2				;
   } else {
      curs_prop = 1				;
   }
   if(nl < 0 || term.forw_curs[0] == '\0') {
      curs_prop = 0			;
   }
   (void)ttygets(tty,"dc",term.del_char,40 );
   (void)ttygets(tty,"ce",term.del_line,40 );
   term.ncol = ttygeti(tty,"co") ;
   term.nlin = ttygeti(tty,"li") ;
   twinsiz.ws_col = 0;
   twinsiz.ws_row = 0;
   if((fildes = open("/dev/tty",2)) >= 0) {
         (void)ioctl(fildes,(	0x40000000	|((sizeof( struct winsize)&0xff		)<<16)|('t'<<8)| 104) 	,&twinsiz);
   }
   term.ncol = (twinsiz.ws_col == 0) ? term.ncol : twinsiz.ws_col;
   term.nlin = (twinsiz.ws_row == 0) ? term.nlin : twinsiz.ws_row;
   nlines = (nl != 0) ? abs(nl) : (term.nlin > 0) ? term.nlin - 1 : 20;
   if(curs_prop == 2				) {
      term.dlin = nlines;
   }
   (void)ttygets(tty,"is",buff,40 );
   {
       char *ptr = buff;
       while(((_ctype_+1)[*ptr]&04 ) ) ptr++;
       if(*ptr == '.') {
	   ptr++;
	   while(((_ctype_+1)[*ptr]&04 ) ) ptr++;
       }
       if(*ptr == '*') ptr++;
       printf("%s",ptr);
   } ;
   mv_cursor(1,term.dlin);
   (void)ttygets(tty,"ke",term.unset_keys,40 );
   (void)ttygets(tty,"ks",term.set_keys,40 );
   {
       char *ptr = term.set_keys;
       while(((_ctype_+1)[*ptr]&04 ) ) ptr++;
       if(*ptr == '.') {
	   ptr++;
	   while(((_ctype_+1)[*ptr]&04 ) ) ptr++;
       }
       if(*ptr == '*') ptr++;
       printf("%s",ptr);
   } ;
   (void)ttygets(tty,"kl",buff,40 ); (void)define_key(buff,2 );
   (void)ttygets(tty,"kr",buff,40 ); (void)define_key(buff,6 );
   (void)ttygets(tty,"kd",buff,40 ); (void)define_key(buff,14 );
   (void)ttygets(tty,"ku",buff,40 ); (void)define_key(buff,16 );
   (void)ttygets(tty,"k1",buff,40 ); (void)set_pf_key(buff,1);
   (void)ttygets(tty,"k2",buff,40 ); (void)set_pf_key(buff,2);
   (void)ttygets(tty,"k3",buff,40 ); (void)set_pf_key(buff,3);
   (void)ttygets(tty,"k4",buff,40 ); (void)set_pf_key(buff,4);
   return(0);
}

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

The following code will cause gcc to get a fatal signal when compiled
with the "-O" flag.  This is gcc version 1.34 on a Sun4/110 running
SunOs 4.0.

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

The compile:
gcc -g -v -O   -c lgamma.c -o lgamma.o
gcc version 1.34
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ lgamma.c /tmp/cca01314.cpp
GNU CPP version 1.34
 /usr/local/lib/gcc-cc1 /tmp/cca01314.cpp -quiet -dumpbase lgamma.c -g -O -version -o /tmp/cca01314.s
GNU C version 1.34 (sparc) compiled by GNU C version 1.34.
gcc: Program cc1 got fatal signal 11.

The code:
------------------------------------------------------------------------
extern const double sin (double x);
extern const double log (double x);
extern const double floor (double x);
int	signgam = 0;
static double pi	= 3.1415926535897932384626434;
static double
neg(arg)
double arg;
{
	double t;
	double pos();
	arg = -arg;
	t = floor(arg);
	if (arg - t  > 0.5e0)
	    t += 1.e0;				 
	signgam = (int) (t - 2*floor(t/2));	 
	signgam = signgam - 1 + signgam;	 
	t = arg - t;				 
	if (t < 0.e0) {
	    t = -t;
	    signgam = -signgam;
	}
	return(-log(arg*pos(arg)*sin(pi*t)/pi));
}