This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Optimization bug in 19990214
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: Optimization bug in 19990214
- From: Nathan Sidwell <nathan at acm dot org>
- Date: Tue, 16 Feb 1999 12:38:23 +0000
- Organization: University of Bristol
- Reply-To: nathan at compsci dot bristol dot ac dot uk
Hi,
the new 19990214 snapshot has an optimization bug which was not present in the
previous 19990208 snapshot. I attach a source file suitable for inclusion
in the test suite (I also attach a .ii file).
Here's a session log
nathan@manao:545>ss-g++ -v
Reading specs from /local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/specs
gcc version egcs-2.93.08 19990214 (gcc2 ss-980929 experimental)
nathan@manao:546>uname -a
SunOS manao 5.6 Generic_105181-03 sun4u sparc
nathan@manao:547>ss-g++ -O1 inline.ii
nathan@manao:548>a.out
A number 1, a string 'PASS'
PASS
nathan@manao:549>ss-g++ -O2 inline.ii
nathan@manao:550>a.out
A number 1, a string 'FAIL 1'
FAIL
The .s file i've attached is that from ss-g++ -O2. Here's the annotated body of
main, showing what are the erroneous bits of code. I've referred to the first
varadic argument as arg0 and the second as arg1. They both have the same type,
Arg.
ld [%fp-44], %o2 ;??
mov 1, %o0 ;%o0 holds the integer 1
sethi %hi(Label1), %o4 ;%o4 holds addr of Label1
sethi %hi(Label2), %o1 ;%o1 holds addr of Label2
st %o0, [%fp-36] ;??
or %o4, %lo(Label1), %o4
st %o2, [%fp-28]
st %o0, [%fp-20] ;init arg0.value
or %o1, %lo(Label2), %o1
sethi %hi(ok), %o3 ;%o3 holds addr of ok
st %o4, [%fp-24] ;init arg0.type
or %o3, %lo(ok), %o3
add %fp, -48, %o2 ;create pointer to arg1 (why?)
st %o1, [%fp-44] ;init arg1.type
sethi %hi(.LLC0), %o0 ;%o0 now holds the format string
st %o3, [%o2+8] ;[%o2+8] == [%fp-40] init arg1.value
or %o0, %lo(.LLC0), %o0
st %o4, [%fp-40] ;CLOBBER [%fp-40] arg1.value
call Foo__FPCce, 0
add %fp, -28, %o1
nathan
--
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
You can up the bandwidth, but you can't up the speed of light
nathan@acm.org http://www.cs.bris.ac.uk/~nathan/ nathan@cs.bris.ac.uk
// Copyright (C) 1999 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 16 Feb 1999 <nathan@acm.org>
// Fails at -O2
#include <stdarg.h>
#include <stdio.h>
struct Arg
{
int s;
char const *label;
void *value;
Arg(char const *label_, void *v)
:label(label_), value(v){}
};
char Label1[] = "FAIL 1";
char Label2[] = "FAIL 2";
inline Arg Baz1(int object)
{
Arg result(Label1, (void *)(object));
return result;
}
inline Arg Baz2(char const *object)
{
return Arg(Label2, (void *)object);
}
int Foo(char const *, ...) throw();
char ok[] = "PASS";
int main()
{
if(Foo("A number %d, a string '%s'\n", Baz1(1), Baz2(ok)))
printf("FAIL\n");
else
printf("PASS\n");
return 0;
}
int Foo(char const *form, ...) throw()
{
va_list args;
va_start(args, form);
Arg *a1 = &va_arg(args, Arg);
Arg *a2 = &va_arg(args, Arg);
int i = (int)a1->value;
char const *s = (char const *)a2->value;
printf(form, i, s);
va_end(args);
return i != 1 || s != ok;
}
# 1 "inline.C"
# 1 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/stdarg.h" 1 3 4
# 1 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/va-sparc.h" 1 3 4
typedef void * __gnuc_va_list;
# 47 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/va-sparc.h" 3 4
void va_end (__gnuc_va_list);
enum __va_type_classes {
__no_type_class = -1,
__void_type_class,
__integer_type_class,
__char_type_class,
__enumeral_type_class,
__boolean_type_class,
__pointer_type_class,
__reference_type_class,
__offset_type_class,
__real_type_class,
__complex_type_class,
__function_type_class,
__method_type_class,
__record_type_class,
__union_type_class,
__array_type_class,
__string_type_class,
__set_type_class,
__file_type_class,
__lang_type_class
};
# 134 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/va-sparc.h" 3 4
# 159 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/va-sparc.h" 3 4
# 30 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/stdarg.h" 2 3 4
# 132 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/stdarg.h" 3 4
typedef __gnuc_va_list va_list;
# 204 "/local/nathan/ss/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.93.08/include/stdarg.h" 3 4
# 6 "inline.C" 2
# 1 "/usr/include/stdio.h" 1 3 4
#pragma ident "@(#)stdio.h 1.49 97/05/09 SMI"
# 1 "/usr/include/sys/feature_tests.h" 1 3 4
#pragma ident "@(#)feature_tests.h 1.13 97/06/26 SMI"
extern "C" {
}
# 17 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/sys/va_list.h" 1 3 4
#pragma ident "@(#)va_list.h 1.6 96/01/26 SMI"
extern "C" {
# 41 "/usr/include/sys/va_list.h" 3 4
typedef void *__va_list;
}
# 18 "/usr/include/stdio.h" 2 3 4
extern "C" {
typedef unsigned int size_t;
typedef long long __longlong_t;
typedef long off_t;
typedef __longlong_t off64_t;
typedef long fpos_t;
typedef __longlong_t fpos64_t;
# 122 "/usr/include/stdio.h" 3 4
typedef struct
{
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
unsigned char _flag;
unsigned char _file;
} FILE;
extern FILE __iob[20 ];
extern FILE *_lastbuf;
extern unsigned char *_bufendtab[];
extern unsigned char _sibuf[], _sobuf[];
# 222 "/usr/include/stdio.h" 3 4
extern int remove(const char *);
extern int rename(const char *, const char *);
extern FILE *tmpfile(void);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern void setbuf(FILE *, char *);
extern void setbuffer(FILE *, char *, size_t);
extern int setlinebuf(FILE *);
extern int setvbuf(FILE *, char *, int, size_t);
extern int fprintf(FILE *, const char *, ...);
extern int fscanf(FILE *, const char *, ...);
extern int printf(const char *, ...);
extern int scanf(const char *, ...);
extern int snprintf(char *, size_t, const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int sscanf(const char *, const char *, ...);
extern int vfprintf(FILE *, const char *, __va_list);
extern int vprintf(const char *, __va_list);
extern int vsnprintf(char *, size_t, const char *, __va_list);
extern int vsprintf(char *, const char *, __va_list);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(FILE *, long, int);
extern int fsetpos(FILE *, const fpos_t *);
extern long ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);
extern int __filbuf(FILE *);
extern int __flsbuf(int, FILE *);
extern FILE *fdopen(int, const char *);
extern char *ctermid(char *);
extern int fileno(FILE *);
# 319 "/usr/include/stdio.h" 3 4
extern FILE *popen(const char *, const char *);
extern char *cuserid(char *);
extern char *tempnam(const char *, const char *);
extern int getopt(int, char *const *, const char *);
extern int getsubopt(char **, char *const *, char **);
extern char *optarg;
extern int optind, opterr, optopt;
extern int getw(FILE *);
extern int putw(int, FILE *);
extern int pclose(FILE *);
extern int fseeko(FILE *, off_t, int);
extern off_t ftello(FILE *);
extern FILE *fopen64(const char *, const char *);
extern FILE *freopen64(const char *, const char *, FILE *);
extern FILE *tmpfile64(void);
extern int fgetpos64(FILE *, fpos64_t *);
extern int fsetpos64(FILE *, const fpos64_t *);
extern int fseeko64(FILE *, off64_t, int);
extern off64_t ftello64(FILE *);
# 467 "/usr/include/stdio.h" 3 4
# 515 "/usr/include/stdio.h" 3 4
}
# 7 "inline.C" 2
struct Arg
{
int s;
char const *label;
void *value;
Arg(char const *label_, void *v)
:label(label_), value(v){}
};
char Label1[] = "FAIL 1";
char Label2[] = "FAIL 2";
inline Arg Baz1(int object)
{
Arg result(Label1, (void *)(object));
return result;
}
inline Arg Baz2(char const *object)
{
return Arg(Label2, (void *)object);
}
int Foo(char const *, ...) throw();
char ok[] = "PASS";
int main()
{
if(Foo("A number %d, a string '%s'\n", Baz1(1), Baz2(ok)))
printf("FAIL\n");
else
printf("PASS\n");
return 0;
}
int Foo(char const *form, ...) throw()
{
va_list args;
(__builtin_next_arg ( form ), args = (char *) __builtin_saveregs ()) ;
Arg *a1 = & __extension__ (*({((__builtin_classify_type (*( Arg *) 0) >= __record_type_class || (__builtin_classify_type (*( Arg *) 0) == __real_type_class && sizeof ( Arg ) == 16)) ? (( args ) = (char *)( args ) + (((sizeof ( Arg * ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) , *( Arg **) (void *) ((char *)( args ) - (((sizeof ( Arg * ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) )) : (((sizeof ( Arg ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) == 8 ? ({ union {char __d[sizeof ( Arg )]; int __i[2];} __u; __u.__i[0] = ((int *) (void *) ( args ))[0]; __u.__i[1] = ((int *) (void *) ( args ))[1]; ( args ) = (char *)( args ) + 8; ( Arg *) (void *) __u.__d; }) : (( args ) = (char *)( args ) + (((sizeof ( Arg ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) , (( Arg *) (void *) ((char *)( args ) - (((sizeof ( Arg ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) ))));})) ;
Arg *a2 = & __extension__ (*({((__builtin_classify_type (*( Arg *) 0) >= __record_type_class || (__builtin_classify_type (*( Arg *) 0) == __real_type_class && sizeof ( Arg ) == 16)) ? (( args ) = (char *)( args ) + (((sizeof ( Arg * ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) , *( Arg **) (void *) ((char *)( args ) - (((sizeof ( Arg * ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) )) : (((sizeof ( Arg ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) == 8 ? ({ union {char __d[sizeof ( Arg )]; int __i[2];} __u; __u.__i[0] = ((int *) (void *) ( args ))[0]; __u.__i[1] = ((int *) (void *) ( args ))[1]; ( args ) = (char *)( args ) + 8; ( Arg *) (void *) __u.__d; }) : (( args ) = (char *)( args ) + (((sizeof ( Arg ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) , (( Arg *) (void *) ((char *)( args ) - (((sizeof ( Arg ) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) ))));})) ;
int i = (int)a1->value;
char const *s = (char const *)a2->value;
printf(form, i, s);
((void)0) ;
return i != 1 || s != ok;
}
.file "inline.C"
gcc2_compiled.:
.global Label1
.section ".data"
.align 8
.type Label1,#object
.size Label1,7
Label1:
.asciz "FAIL 1"
.global Label2
.align 8
.type Label2,#object
.size Label2,7
Label2:
.asciz "FAIL 2"
.global ok
.align 8
.type ok,#object
.size ok,5
ok:
.asciz "PASS"
.section ".rodata"
.align 8
.LLC0:
.asciz "A number %d, a string '%s'\n"
.align 8
.LLC1:
.asciz "FAIL\n"
.align 8
.LLC2:
.asciz "PASS\n"
.section ".text"
.align 4
.global main
.type main,#function
.proc 04
main:
.LLFB1:
!#PROLOGUE# 0
save %sp, -144, %sp
.LLCFI0:
!#PROLOGUE# 1
ld [%fp-44], %o2
mov 1, %o0
sethi %hi(Label1), %o4
sethi %hi(Label2), %o1
st %o0, [%fp-36]
or %o4, %lo(Label1), %o4
st %o2, [%fp-28]
st %o0, [%fp-20]
or %o1, %lo(Label2), %o1
sethi %hi(ok), %o3
st %o4, [%fp-24]
or %o3, %lo(ok), %o3
add %fp, -48, %o2
st %o1, [%fp-44]
sethi %hi(.LLC0), %o0
st %o3, [%o2+8]
or %o0, %lo(.LLC0), %o0
st %o4, [%fp-40]
call Foo__FPCce, 0
add %fp, -28, %o1
cmp %o0, 0
be .LL11
sethi %hi(.LLC2), %o0
sethi %hi(.LLC1), %o0
call printf, 0
or %o0, %lo(.LLC1), %o0
b,a .LL18
.LL11:
call printf, 0
or %o0, %lo(.LLC2), %o0
.LL18:
ret
restore %g0, 0, %o0
.LLFE1:
.LLfe1:
.size main,.LLfe1-main
.global __throw
.align 4
.global Foo__FPCce
.type Foo__FPCce,#function
.proc 04
Foo__FPCce:
.LLFB2:
!#PROLOGUE# 0
save %sp, -144, %sp
.LLCFI1:
!#PROLOGUE# 1
st %i1, [%fp+72]
st %i2, [%fp+76]
st %i3, [%fp+80]
st %i4, [%fp+84]
st %i5, [%fp+88]
.LLEHB20:
mov %i1, %o2
mov %i2, %o1
mov %i0, %o0
ld [%o1+8], %i1
ld [%o2+8], %i0
mov %i1, %o2
call printf, 0
mov %i0, %o1
cmp %i0, 1
bne .LL29
mov 0, %i0
sethi %hi(ok), %o0
or %o0, %lo(ok), %o0
cmp %i1, %o0
be .LL41
nop
.LL29:
b .LL42
mov 1, %i0
.LLEHE20:
.LL21:
call __throw, 0
nop
.LLEHB38:
.LLEHB32:
.LL20:
call __start_cp_handler, 0
nop
mov %o0, %i0
.LLEHB34:
mov 0, %o0
call __check_eh_spec, 0
add %fp, -48, %o1
.LLEHE34:
.LL35:
call __throw, 0
nop
.LLEHE32:
.LL34:
call __cp_pop_exception, 0
mov %i0, %o0
b,a .LL35
.LL32:
b,a .LL21
.LLEHE38:
.LL38:
call terminate__Fv, 0
nop
.LL42:
.LL41:
ret
restore
.LLFE2:
.LLfe2:
.size Foo__FPCce,.LLfe2-Foo__FPCce
.section ".gcc_except_table",#alloc,#write
.align 4
__EXCEPTION_TABLE__:
.uaword .LLEHB20
.uaword .LLEHE20
.uaword .LL20
.uaword .LLEHB38
.uaword .LLEHE38
.uaword .LL38
.uaword .LLEHB32
.uaword .LLEHE32
.uaword .LL32
.uaword .LLEHB34
.uaword .LLEHE34
.uaword .LL34
.LLRTH1:
.uaword -1
.uaword -1
.section ".eh_frame",#alloc,#write
__FRAME_BEGIN__:
.uaword .LLECIE1-.LLSCIE1
.LLSCIE1:
.uaword 0x0
.byte 0x1
.asciz "eh"
.uaword __EXCEPTION_TABLE__
.byte 0x1
.byte 0x7c
.byte 0x65
.byte 0xc
.byte 0xe
.byte 0x0
.byte 0x9
.byte 0x65
.byte 0xf
.align 4
.LLECIE1:
.uaword .LLEFDE1-.LLSFDE1
.LLSFDE1:
.uaword .LLSFDE1-__FRAME_BEGIN__
.uaword .LLFB1
.uaword .LLFE1-.LLFB1
.byte 0x4
.uaword .LLCFI0-.LLFB1
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE1:
.uaword .LLEFDE3-.LLSFDE3
.LLSFDE3:
.uaword .LLSFDE3-__FRAME_BEGIN__
.uaword .LLFB2
.uaword .LLFE2-.LLFB2
.byte 0x4
.uaword .LLCFI1-.LLFB2
.byte 0xd
.byte 0x1e
.byte 0x2d
.byte 0x9
.byte 0x65
.byte 0x1f
.align 4
.LLEFDE3:
.ident "GCC: (GNU) egcs-2.93.08 19990214 (gcc2 ss-980929 experimental)"