Article View: gnu.gcc.bug
Article #273GCC -O2 for i386
From: Bruno Haible
Date: Sun, 26 Jul 1992 00:17
Date: Sun, 26 Jul 1992 00:17
347 lines
11283 bytes
11283 bytes
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
Technical Details
Message-ID:
<9207252017.AA04106@ma2s2.mathematik.uni-karlsruhe.de>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!ma2s2.mathematik.uni-karlsruhe.de!haibleShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!ma2s2.mathematik.uni-karlsruhe.de!haible From: haible@ma2s2.mathematik.uni-karlsruhe.de (Bruno Haible) Subject: GCC -O2 for i386 Message-ID: <9207252017.AA04106@ma2s2.mathematik.uni-karlsruhe.de> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Sun, 26 Jul 1992 00:17:38 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 349