Does Clang correctly compile inline assembly?

Hi!

I wonder if the following code snippet with assembly is broken, or Clang is wrong:

$ cat tmp/asm/rsp.c
void cpuid2 ( unsigned int* eax, unsigned int* ebx, unsigned int* ecx, unsigned int* edx,
unsigned int index, unsigned int ecx_in )
{
unsigned int a, b, c, d;
asm volatile (“push %%ebx\n\tcpuid\n\tmovl %%ebx, %%esi\n\tpop%%ebx”
: “=a” (a), “=S” (b), “=c” (c), “=d” (d)
: “0” (index), “2”(ecx_in) );
*eax = a; *ebx = b; *ecx = c; *edx = d;
}

$ ./bin/clang tmp/asm/rsp.c -c -o tmp/asm/rsp.o
$ objdump -d tmp/asm/rsp.o
<…>

0000000000000000 :
0: 48 89 7c 24 f8 mov %rdi,-0x8(%rsp) <---- %rdi is saved on stack
5: 48 89 74 24 f0 mov %rsi,-0x10(%rsp)
f: 48 89 4c 24 e0 mov %rcx,-0x20(%rsp)
14: 44 89 44 24 dc mov %r8d,-0x24(%rsp)
19: 44 89 4c 24 d8 mov %r9d,-0x28(%rsp)
1e: 44 8b 44 24 dc mov -0x24(%rsp),%r8d
23: 44 8b 4c 24 d8 mov -0x28(%rsp),%r9d
28: 44 89 c0 mov %r8d,%eax
2b: 44 89 c9 mov %r9d,%ecx
2e: 53 push %rbx <--------------------------- % rbx is pushed on stack and overwrites %rdi
2f: 0f a2 cpuid
31: 89 de mov %ebx,%esi
33: 5b pop %rbx
34: 89 44 24 d4 mov %eax,-0x2c(%rsp)
38: 89 74 24 d0 mov %esi,-0x30(%rsp)
3c: 89 4c 24 cc mov %ecx,-0x34(%rsp)
40: 89 54 24 c8 mov %edx,-0x38(%rsp)
44: 8b 44 24 d4 mov -0x2c(%rsp),%eax
48: 48 8b 7c 24 f8 mov -0x8(%rsp),%rdi <----- %rdi is restored incorrectly
4d: 89 07 mov %eax,(%rdi)
<…>

Adding %rsp to the clobber-list doesn’t help (and doesn’t change generated code).