FW: RE: x86_64 port

Simon Marlow simonmar at microsoft.com
Tue Mar 8 08:25:37 EST 2005

On 07 March 2005 18:01, Kurt Roeckx 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
> I get the same with both gcc-3.3 and gcc-3.4.  They generate
> identical code.
>> 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.
> It looks to me like it's using eax/rax instead of r13 to me.
> It's probably doing some optimizing it shouldn't, but on the
> other hand isn't "wrong".
> Anyway, as summary:
> - It's using a movl where it should use a movq
> - It's probably doing some optimizations it shouldn't, but
>   they're not "wrong" in this testcase and probably can't be
>   avoided because of the way gcc works.
>   Those happen on both i386 and amd64.

The question of whether this behaviour is wrong or not is interesting.
On the face of it, the generated code is incorrect because it doesn't
implement the semantics of the original program.

However, we have to be clear about what the semantics of the original
program *is*.  The register annotation is just an annotation, and
therefore doesn't affect the semantics.  But the gcc manual has this to
say about computed goto:

  You may not use this mechanism to jump to code in a different

So, perhaps the example program relies on undefined behaviour.  But, you
can change the example program so that gcc has no idea where it's
jumping to, and gcc will still generate incorrect code.  So in fact it
has nothing to do with the jump destination being outside the current

It's a bug.


More information about the Glasgow-haskell-users mailing list