
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

On Mon, Mar 07, 2005 at 04:59:38PM -0000, Simon Marlow wrote:
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.
gcc 3.3.4 on AMD64 appears to generate correct code when the dummy call is present. Ick. Dave

In message <20050307171501.GA15936@old.davidb.org> David Brown
On Mon, Mar 07, 2005 at 04:59:38PM -0000, Simon Marlow wrote:
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.
This all appears to be the same for Sparc. With: register void * R1 __asm__("%g7"); extern void g(void); static void f(void) { R1 = g; goto *R1; } (BTW I have no idea if register g7 is a sensible choice here! So this test may be meaningless!) We get: sethi %hi(g), %g1 jmp %g1+%lo(g) nop While with the dummy() call inserted: sethi %hi(g), %g1 call dummy, 0 or %g1, %lo(g), %g7 jmp %g7 nop we actually get any mention of %g7 at all. This is with gcc 3.3.5 on Sparc Linux (Gentoo). Duncan

On Mon, Mar 07, 2005 at 09:15:01AM -0800, David Brown wrote:
gcc 3.3.4 on AMD64 appears to generate correct code when the dummy call is present. Ick.
It generates the following code here: subq $8, %rsp movl $g, %r13d movl $0, %eax call dummy jmp *%r13 Which still has the movl vs movq problem. Kurt
participants (4)
-
David Brown
-
Duncan Coutts
-
Kurt Roeckx
-
Simon Marlow