This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Optimization bug in 19990214


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)"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]