From: fjh AT cs DOT mu DOT OZ DOT AU (Fergus Henderson) Subject: gcc 2.7-b19 on gnu-win32 b19 generating bad asm 28 Jul 1998 11:56:57 -0700 Message-ID: <19980728070132.40820.cygnus.gnu-win32@murlibobo.cs.mu.OZ.AU> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii To: GNU C Bug Reports , Cygnus GNU-win32 mailing list Cc: mercury-bugs AT cs DOT mu DOT OZ DOT AU 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 | "I have always known that the pursuit WWW: | of excellence is a lethal habit" PGP: finger fjh AT 128 DOT 250 DOT 37 DOT 3 | -- the last words of T. S. Garp. - For help on using this list (especially unsubscribing), send a message to "gnu-win32-request AT cygnus DOT com" with one line of text: "help".