From: haible@ma2s2.mathematik.uni-karlsruhe.de (Bruno Haible)
Subject: GCC -O2 for i386
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sun, 26 Jul 1992 00:17:38 GMT

I have found a bug in GCC's i386 code generation.
I'm using GCC version 2.2.2, configured as i386-linux by H.J.Lu.

gcc -O -S array.i ; cat array.s
is OK.
gcc -O2 -S array.i ; cat array.s
uncovers a bug: The instruction marked 'INCORRECT' uses %al, but
%eax has not been set before, so contains garbage.

======================= array.i ================================================
  typedef char           BYTE;      
  typedef unsigned char  UBYTE;     
  typedef short          WORD;      
  typedef unsigned short UWORD;     
  typedef long           LONG;      
  typedef unsigned long  ULONG;     
  typedef unsigned int  boolean;
  typedef signed int  signean;
  typedef UBYTE   uint1;    
  typedef BYTE    sint1;    
  typedef UBYTE   uint2;    
  typedef BYTE    sint2;    
  typedef UBYTE   uint3;    
  typedef BYTE    sint3;    
  typedef UBYTE   uint4;    
  typedef BYTE    sint4;    
  typedef UBYTE   uint5;    
  typedef BYTE    sint5;    
  typedef UBYTE   uint6;    
  typedef BYTE    sint6;    
  typedef UBYTE   uint7;    
  typedef BYTE    sint7;    
  typedef UBYTE   uint8;    
  typedef BYTE    sint8;    
  typedef UWORD   uint9;    
  typedef WORD    sint9;    
  typedef UWORD   uint10;   
  typedef WORD    sint10;   
  typedef UWORD   uint11;   
  typedef WORD    sint11;   
  typedef UWORD   uint12;   
  typedef WORD    sint12;   
  typedef UWORD   uint13;   
  typedef WORD    sint13;   
  typedef UWORD   uint14;   
  typedef WORD    sint14;   
  typedef UWORD   uint15;   
  typedef WORD    sint15;   
  typedef UWORD   uint16;   
  typedef WORD    sint16;   
  typedef ULONG   uint17;   
  typedef LONG    sint17;   
  typedef ULONG   uint18;   
  typedef LONG    sint18;   
  typedef ULONG   uint19;   
  typedef LONG    sint19;   
  typedef ULONG   uint20;   
  typedef LONG    sint20;   
  typedef ULONG   uint21;   
  typedef LONG    sint21;   
  typedef ULONG   uint22;   
  typedef LONG    sint22;   
  typedef ULONG   uint23;   
  typedef LONG    sint23;   
  typedef ULONG   uint24;   
  typedef LONG    sint24;   
  typedef ULONG   uint25;   
  typedef LONG    sint25;   
  typedef ULONG   uint26;   
  typedef LONG    sint26;   
  typedef ULONG   uint27;   
  typedef LONG    sint27;   
  typedef ULONG   uint28;   
  typedef LONG    sint28;   
  typedef ULONG   uint29;   
  typedef LONG    sint29;   
  typedef ULONG   uint30;   
  typedef LONG    sint30;   
  typedef ULONG   uint31;   
  typedef LONG    sint31;   
  typedef ULONG   uint32;   
  typedef LONG    sint32;   
  typedef   sint8        sintB;
  typedef   uint8      uintB;
  typedef   sint16        sintW;
  typedef   uint16      uintW;
  typedef   sint32        sintL;
  typedef   uint32      uintL;
  typedef struct { sintL hi; uintL lo; } sintL2;  
  typedef struct { uintL hi; uintL lo; } uintL2;  
  typedef   sint16         sintBW;
  typedef   uint16       uintBW;
  typedef   sint32         sintWL;
  typedef   uint32       uintWL;
  typedef   sint32         sintBWL;
  typedef   uint32       uintBWL;
  typedef   uint32      uintD;
  typedef   sint32        sintD;
  typedef  void *  object;
  typedef  uintL  oint;
extern object* STACK; 
  typedef   uint8      tint;
  typedef   uint24      aint;
typedef struct { union { object _GCself; uintB flags[4]; } header;   
                 uintL  length;    
               }
        sarray_;
typedef sarray_ *  Sarray;
typedef struct { union { object _GCself; uintB flags[4]; } header;   
                 uintL  length;    
                 uint8  data[0 ];  
               }
        sbvector_;
typedef sbvector_ *  Sbvector;
typedef struct { union { object _GCself; uintB flags[4]; } header;   
                 uintL  length;    
                 uintB  data[0 ];  
               }
        sstring_;
typedef sstring_ *  Sstring;
typedef struct { union { object _GCself; uintB flags[4]; } header;   
                 uintL  length;    
                 object data[0 ];  
               }
        svector_;
typedef svector_ *  Svector;
typedef struct { union { object _GCself; uintB flags[4]; } header;    
                 uintB flags;       
                 uintWL  rank;        
                 object data;       
                 uintL totalsize;   
                 uintL dims[0 ];  
               }
        array_;
typedef array_ *  Array;
    typedef void Values;
    typedef Values (*lisp_function)();
  typedef struct { lisp_function function;  
                   object name;             
                   object keywords;         
                   uintW argtype;           
                   uintW req_anz;           
                   uintW opt_anz;           
                   uintB rest_flag;         
                   uintB key_flag;          
                   uintW key_anz;           
                 }
          subr_;
  typedef subr_ *  Subr;
    extern uintWL  mv_count;
  extern object mv_space [ 128 -1];
    extern object subr_self;
  extern  volatile  void fehler (const char * errorstring);
   static   volatile  void fehler_vector (object obj);
   static   volatile  void fehler_vector(    
       register  object obj)
    {  ( (STACK[-1-(-1)])  = (obj), STACK  -=  -1) ;  ( (STACK[-1-(-1)])  = ( ((Subr)(((0 ==0) && (((oint)((object)( ((oint)(tint)(     0x0D  ) << 24 ) + (oint)(aint)(0) ))  &  0xFFFFFFFFUL  ) == 0) ? (void*)(subr_self) : (void*) ((void*)(((aint)((oint)(subr_self) >> 0 ) & (0x00FFFFFFUL  >> 0 )) ))  ) )) ->name), STACK  -=  -1) ;
      fehler(
              1  ? "~: ~ ist kein Vektor." :
              0  ? "~: ~ is not a vector" :
             ""
            );
    }
   static  uintL* get_fill_pointer (object obj);
   static  uintL* get_fill_pointer(    
       register  object obj)
    {  
      {   register  object obj_from_if_vectorp = (obj);    register  tint type_from_if_vectorp = ((tint)((oint)(obj_from_if_vectorp) >> 24 )) ; type_from_if_vectorp = type_from_if_vectorp & ~ (1L<<( 2  )) ; if (!(type_from_if_vectorp==0)&&(type_from_if_vectorp<=   0x07  ))  ;  else  { fehler_vector(obj); } } ;
      {   register  object obj_from_if_simplep = (obj);    register  tint type_from_if_simplep = ((tint)((oint)(obj_from_if_simplep) >> 24 )) ; if (!(type_from_if_simplep==0)&&(type_from_if_simplep<=  0x03  ))  { goto fehler_fillp; }  else  ;  } ;
      if (!( ((Array)(((0 ==0) && (((oint)((object)( ((oint)(tint)(    0x04  ) << 24 ) + (oint)(aint)(0) ))  &  0xFFFFFFFFUL  ) == 0) ? (void*)(obj) : (void*) ((void*)(((aint)((oint)(obj) >> 0 ) & (0x00FFFFFFUL  >> 0 )) ))  ) )) ->flags &  (1L<<(      6 )) )) { goto fehler_fillp; }
      return (( ((Array)(((0 ==0) && (((oint)((object)( ((oint)(tint)(    0x04  ) << 24 ) + (oint)(aint)(0) ))  &  0xFFFFFFFFUL  ) == 0) ? (void*)(obj) : (void*) ((void*)(((aint)((oint)(obj) >> 0 ) & (0x00FFFFFFUL  >> 0 )) ))  ) )) ->flags &  (1L<<( 4 )) )
              ? & ((Array)(((0 ==0) && (((oint)((object)( ((oint)(tint)(    0x04  ) << 24 ) + (oint)(aint)(0) ))  &  0xFFFFFFFFUL  ) == 0) ? (void*)(obj) : (void*) ((void*)(((aint)((oint)(obj) >> 0 ) & (0x00FFFFFFUL  >> 0 )) ))  ) )) ->dims[2]  
              : & ((Array)(((0 ==0) && (((oint)((object)( ((oint)(tint)(    0x04  ) << 24 ) + (oint)(aint)(0) ))  &  0xFFFFFFFFUL  ) == 0) ? (void*)(obj) : (void*) ((void*)(((aint)((oint)(obj) >> 0 ) & (0x00FFFFFFUL  >> 0 )) ))  ) )) ->dims[1]  
             );
      fehler_fillp:
         ( (STACK[-1-(-1)])  = (obj), STACK  -=  -1) ;  ( (STACK[-1-(-1)])  = ( ((Subr)(((0 ==0) && (((oint)((object)( ((oint)(tint)(     0x0D  ) << 24 ) + (oint)(aint)(0) ))  &  0xFFFFFFFFUL  ) == 0) ? (void*)(subr_self) : (void*) ((void*)(((aint)((oint)(subr_self) >> 0 ) & (0x00FFFFFFUL  >> 0 )) ))  ) )) ->name), STACK  -=  -1) ;
        fehler(
                1  ? "~: Vektor ~ hat keinen Fill-Pointer." :
                0  ? "~: vector ~ has no fill pointer" :
               ""
              );
    }
============== array.s compiled with -O ========================================
	.file	"array.i"
gcc2_compiled.:
.text
LC0:
	.ascii "~: ~ ist kein Vektor.\0"
	.align 2
_fehler_vector:
	pushl %ebp
	movl %esp,%ebp
	movl _STACK,%eax
	movl 8(%ebp),%ecx
	movl %ecx,(%eax)
	movl _STACK,%edx
	addl $4,%edx
	movl %edx,_STACK
	movl _subr_self,%eax
	andl $16777215,%eax
	movl 4(%eax),%eax
	movl %eax,(%edx)
	addl $4,_STACK
	pushl $LC0
	call _fehler
	.align 2,0x90
LC1:
	.ascii "~: Vektor ~ hat keinen Fill-Pointer.\0"
	.align 2
_get_fill_pointer:
	pushl %ebp
	movl %esp,%ebp
	movl 8(%ebp),%ecx
	movl %ecx,%eax
	shrl $24,%eax
	andb $251,%al
	je L3
	cmpb $7,%al
	jbe L4
L3:
	pushl %ecx
	call _fehler_vector
	.align 2,0x90
L4:
	movl %ecx,%eax
	shrl $24,%eax
	testb %al,%al
	je L7
	cmpb $3,%al
	jbe L6
L7:
	movl %ecx,%edx
	andl $16777215,%edx
	movb 4(%edx),%al
	andb $64,%al
	je L6
	movb 4(%edx),%al
	andb $16,%al
	je L9
	leal 28(%edx),%eax
	leave
	ret
	.align 2,0x90
L9:
	movl %ecx,%eax
	andl $16777215,%eax
	addl $24,%eax
	leave
	ret
	.align 2,0x90
L6:
	movl _STACK,%eax
	movl %ecx,(%eax)
	movl _STACK,%edx
	addl $4,%edx
	movl %edx,_STACK
	movl _subr_self,%eax
	andl $16777215,%eax
	movl 4(%eax),%eax
	movl %eax,(%edx)
	addl $4,_STACK
	pushl $LC1
	call _fehler
	.align 2,0x90
============= array.s compiled with -O2 ========================================
	.file	"array.i"
gcc2_compiled.:
.text
LC0:
	.ascii "~: ~ ist kein Vektor.\0"
	.align 2
_fehler_vector:
	pushl %ebp
	movl %esp,%ebp
	movl _STACK,%eax
	movl 8(%ebp),%ecx
	movl %ecx,(%eax)
	movl _STACK,%edx
	addl $4,%edx
	movl %edx,_STACK
	movl _subr_self,%eax
	andl $16777215,%eax
	movl 4(%eax),%eax
	movl %eax,(%edx)
	addl $4,_STACK
	pushl $LC0
	call _fehler
	.align 2,0x90
LC1:
	.ascii "~: Vektor ~ hat keinen Fill-Pointer.\0"
	.align 2
_get_fill_pointer:
	pushl %ebp
	movl %esp,%ebp
	movl 8(%ebp),%ecx
	movl %ecx,%edx
	shrl $24,%edx
	testb $251,%dl
	je L3
	cmpb $7,%al				; INCORRECT
	jbe L4
L3:
	pushl %ecx
	call _fehler_vector
	.align 2,0x90
L4:
	movb %dl,%al
	testb %al,%al
	je L7
	cmpb $3,%al
	jbe L6
L7:
	movl %ecx,%edx
	andl $16777215,%edx
	movb 4(%edx),%al
	andb $64,%al
	je L6
	movb 4(%edx),%al
	andb $16,%al
	je L9
	leal 28(%edx),%eax
	leave
	ret
	.align 2,0x90
L9:
	leal 24(%edx),%eax
	leave
	ret
	.align 2,0x90
L6:
	movl _STACK,%eax
	movl %ecx,(%eax)
	movl _STACK,%edx
	addl $4,%edx
	movl %edx,_STACK
	movl _subr_self,%eax
	andl $16777215,%eax
	movl 4(%eax),%eax
	movl %eax,(%edx)
	addl $4,_STACK
	pushl $LC1
	call _fehler
	.align 2,0x90
================================================================================

Bruno Haible
haible@ma2s2.mathematik.uni-karlsruhe.de


Newsgroups: gnu.gcc.bug