[cfe-dev] __builtin_va_list issue with -ccc-host-triple x86_64-pc-win32-macho
Andrew Fish
afish at apple.com
Mon Apr 11 15:42:31 PDT 2011
I realized that va_list is not really part of the ABI and the compiler can implement it any way it wants, but it looks like in the x86_64-pc-win32-macho triple there is a mixture of the Unix 24 byte array of structure scheme and the Visual Studio 8 byte pointer to the frame scheme.
I've seen a failure using a va_list that looks a lot like the schemes were being mixed, but the code was so complicated it is hard to say for sure. I tried to generate a simple test case and it looked like the code gen for the va_list was following Visual Studio scheme of being a pointer to the frame, but the sizeof (__builtin_va_list) is still 24 bytes. Given this I think it is safe to assume that the x86_64-pc-win32-macho triple has a bug that is mixing va_list schemes. For our EFI usage case we don't care which scheme is used, we just need the compiler to be self consistent. Xcode also shows the va_list as an array of a structure that is 24 bytes.
Test case:
clang -Os -S v.c -ccc-host-triple x86_64-pc-win32-macho
clang -Os -S v.c
As you can see in the attached files the code gen for the va_list is different (and the calling conventions are different too) for clang vs clang -ccc-host-triple x86_64-pc-win32-macho.
int
ReturnMarker (
VA_LIST Marker
)
{
return VA_ARG (Marker, int);
}
_ReturnMarker: ## @ReturnMarker clang
Leh_func_begin0:
## BB#0:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movslq (%rdi), %rax
cmpq $40, %rax
ja LBB0_2
## BB#1:
movq 16(%rdi), %rcx
addq %rax, %rcx
addl $8, %eax
movl %eax, (%rdi)
jmp LBB0_3
LBB0_2:
movq 8(%rdi), %rcx
leaq 8(%rcx), %rax
movq %rax, 8(%rdi)
LBB0_3:
movl (%rcx), %eax
popq %rbp
ret
_ReturnMarker: ## @ReturnMarker clang -ccc-host-triple x86_64-pc-win32-macho Marker == rcx
Leh_func_begin0:
## BB#0:
movq (%rcx), %rax
leaq 8(%rax), %rdx
movq %rdx, (%rcx)
movl (%rax), %eax
ret
Marker$ = 8
ReturnMarker PROC NEAR cl /FAcs v.c /Os # Visual Studio
; 16 : {
00000 48 89 4c 24 08 mov QWORD PTR [rsp+8], rcx
; 17 : return VA_ARG (Marker, int);
00005 48 8b 44 24 08 mov rax, QWORD PTR Marker$[rsp]
0000a 48 83 c0 08 add rax, 8
0000e 48 89 44 24 08 mov QWORD PTR Marker$[rsp], rax
00013 48 8b 44 24 08 mov rax, QWORD PTR Marker$[rsp]
00018 8b 40 f8 mov eax, DWORD PTR [rax-8]
; 18 : }
0001b c3 ret 0
ReturnMarker ENDP
ret$ = 32
Marker$ = 40
Handle$ = 64
Test PROC NEAR
But sizeof (__builtin_va_list) returns 24 bytes in both cases and this would seem to indicate the compiler using a mixture of va_list schemes?
int
Test2 ()
{
return sizeof (VA_LIST);
}
_Test2: ## @Test2 clang
Leh_func_begin2:
## BB#0:
pushq %rbp
Ltmp5:
movq %rsp, %rbp
Ltmp6:
movl $24, %eax
popq %rbp
ret
_Test2: ## @Test2 clang -ccc-host-triple x86_64-pc-win32-macho
Leh_func_begin2:
## BB#0:
movl $24, %eax
ret
Any help on fixing this would be greatly appreciated.
One more thing, in the failing case the va_list was being passed on the stack and not in a register since it was the 5th or 6th argument.
Thanks,
Andrew Fish
clang -v
clang version 3.0 (trunk 127294)
Target: x86_64-apple-darwin10
Thread model: posix
PS I also noticed that the clang -ccc-host-triple x86_64-pc-win32-macho is not reserving the 32 bytes on the stack so the callee can spill the registers. I think this may be a violation of the 64-bit Windows calling convention?
_Test: ## @Test
Leh_func_begin1:
## BB#0:
subq $24, %rsp
Ltmp0:
movq %r9, 56(%rsp)
movq %r8, 48(%rsp)
movq %rdx, 40(%rsp)
leaq 40(%rsp), %rax
movq %rax, (%rsp)
leaq 48(%rsp), %rax
movq %rax, (%rsp)
movl 40(%rsp), %eax
addq $24, %rsp
ret
ret$ = 32
Marker$ = 40
Handle$ = 64
Test PROC NEAR
; 26 : {
$LN3:
00030 48 89 4c 24 08 mov QWORD PTR [rsp+8], rcx
00035 48 89 54 24 10 mov QWORD PTR [rsp+16], rdx
0003a 4c 89 44 24 18 mov QWORD PTR [rsp+24], r8
0003f 4c 89 4c 24 20 mov QWORD PTR [rsp+32], r9
00044 48 83 ec 38 sub rsp, 56 ; 00000038H
; 27 : VA_LIST Marker;
; 28 : int ret;
; 29 :
; 30 : VA_START (Marker, Handle);
00048 48 8d 44 24 48 lea rax, QWORD PTR Handle$[rsp+8]
0004d 48 89 44 24 28 mov QWORD PTR Marker$[rsp], rax
; 31 : ret = ReturnMarker (Marker);
00052 48 8b 4c 24 28 mov rcx, QWORD PTR Marker$[rsp]
00057 e8 00 00 00 00 call ReturnMarker
0005c 89 44 24 20 mov DWORD PTR ret$[rsp], eax
; 32 : VA_END (Marker);
00060 48 c7 44 24 28
00 00 00 00 mov QWORD PTR Marker$[rsp], 0
; 33 :
; 34 : return ret;
00069 8b 44 24 20 mov eax, DWORD PTR ret$[rsp]
; 35 : }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v.c
Type: application/octet-stream
Size: 762 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v.x86_64-pc-win32-macho.s
Type: application/octet-stream
Size: 4496 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment-0001.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment-0002.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v.s
Type: application/octet-stream
Size: 6689 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment-0002.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110411/e74de4bc/attachment-0003.html>
More information about the cfe-dev
mailing list