Subject: gcc 2.7-b19 on gnu-win32 b19 generating bad asm
From: [email-masked] (Fergus Henderson)

28 Jul 1998 11:56:57 -0700
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
To: GNU C Bug Reports <[email-masked]>,
        Cygnus GNU-win32 mailing list <[email-masked]>
Cc: [email-masked]

GNU C version 2.7-b19 on gnu-win32 version b19.1 (intel x86)
generates bad assembler for the following program.  The program
(cut down from C code automatically generated by the Mercury compiler)
is not strictly conforming, but even so, the generated assembler
is pretty nonsensical.  This worked fine in b18.

To reproduce the problem, compile the following program with `gcc -O2 -S'.

/*--- cut here --------------------------------------------------------------*/
void abort(void);

typedef	unsigned int 	Word;
typedef int 		Integer;
typedef void			Code;

register	Word	mr0 __asm__("esi");	 
register	Word	mr1 __asm__("edi");	 
register	Word	mr2 __asm__("ebx");	 

typedef struct MR_mercury_engine_struct {
	Word		fake_reg[1024];
} MercuryEngine;

extern MercuryEngine	MR_engine_base;

extern void  mercury__compare_3_3 (void) __asm__("_entry_" "mercury__compare_3_3" ) ;

static  void  foo_module (void);
static  void  foo_module (void) { __asm__ __volatile__("" : : "g"(  foo_module  )) ; __asm__ __volatile__("" : : "g"( &&   foo_module_dummy_label   )) ;   foo_module_dummy_label  : { 
	__asm__ __volatile__("" : : "g"( && foo_entry  )) ;   ;
	  ;
} return; { 
 	 _entry_foo_entry      :	__asm__ __volatile__(	"	.globl _entry_" "foo_entry"  "\n" 	 	"_entry_" "foo_entry"  ":\n" 	 	);	 skip_foo_entry      : ; 	}	 foo_entry :	__asm__ __volatile__("" : : "g"( &&  _entry_foo_entry      )) ;	{ ;
	(	((void)0) ,	((void)0) ,	(( Word * )(  (  mr0 )  ))   = (( Word * )(  (  mr0 )  ))   + ( 11 ),	((void)0) ,	(void)0	) ;
	((( Word * )(  (  mr0 )  ))  [- 11 ])  = (Word) (( Code * )(  (  mr1 )  ))   ;
	(  ((MR_engine_base. fake_reg ) ) [7]  )   = ((const Word *) (( (  (  ((MR_engine_base. fake_reg ) ) [3]  )   ) ) - (  ( ( 1 )  ) )) )[  (Integer) 3 ] ;
	(  ((MR_engine_base. fake_reg ) ) [12]  )   = ((const Word *) (( (  (  ((MR_engine_base. fake_reg ) ) [3]  )   ) ) - (  ( ( 1 )  ) )) )[  (Integer) 0 ] ;
	if (((Integer) (  ((MR_engine_base. fake_reg ) ) [7]  )   != (Integer) (const Word *) ((const Word *)((const char *)(  (( (Integer) 0 ) << 2  )  ) + ( ( 0 )  ))) ))
		do { ((void)0) ; goto  foo_label ; } while(0) ;
	do {	((void)0) ;	do {	((void)0) ;	(( Code * )(  (  mr1 )  ))   = (  (&&  _entry_foo_label       )  );	((void)0) ;	do { ((void)0) ; { register int stack_pointer __asm__("esp");	__asm__("" : : "g"(stack_pointer)); }	goto *(    (  (& mercury__compare_3_3 )   )    )  ; } while(0) ;	} while (0)  ;	} while (0) ;
	abort();
 	 _entry_foo_label       :	 	 skip_foo_label       : ; 	}	  foo_label  :	{  ;
	abort();
} } 
/*--- cut here --------------------------------------------------------------*/

The generated code for the `goto' above is the assembler statement

	jmp *%ecx

but this is the *only* occurrence of %ecx in the generated code.
%ecx is never initialized, and the reference to `mercury__compare_3_3'
somehow gets optimized away entirely.

[Incidentally, the obvious alternative of using an inline asm jmp instead
of `goto *(...)' didn't work either, because that resulted in a gcc internal
error -- on a different test case, however. I will report that one
separately if I can cut it down to a reasonable size).]

-- 
Fergus Henderson <[email-masked]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [email-masked]        |     -- the last words of T. S. Garp.
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".