
On 07 March 2005 16:40, Simon Marlow wrote:
On 07 March 2005 16:18, David Brown wrote:
On Mon, Mar 07, 2005 at 11:47:31AM -0000, Simon Marlow wrote:
$ cat bug.c register void * R1 __asm__("%r13");
extern void g(void); static void f(void) { R1 = g; goto *R1; } $ gcc -S -O bug.c $
And take a look at the generated assembly for the function f:
f: .LFB2: movl $g, %eax jmp *%rax
Note that the assignment to the global variable R1 has been lost. It works fine on x86 though: change the register variable to %esi and try it.
Hmm. On gcc 3.3.5 that I have, it discards the assignment on x86 as well.
Yes, looks like it fails with 3.4.1 and 3.4.3 I have here, but 3.2.2 works.
Now I'm quite surpised that this hasn't affected us on x86. Very strange.
The mystery as to why this doesn't affect us on x86 is solved: on x86 we generate slightly different C code, including a dummy function call: extern void g(void); static void f(void) { R1 = g; dummy(); goto *R1; } the call to dummy() (which we filter out from the assembly later) is enough to force gcc to emit the assignment to R1. That dummy function call has been there for ever, and the original reason for it has been lost in the mists of time... comments in the source code seemed to indicate that it was probably not necessary any more, so for x86_64 I removed it. It looks like I'll have to reinstate it to work around this bug, though. Cheers, Simon