[cfe-dev] Clang i386-pc-win32 struct return-by-value doesn't match MSVC

Joe Groff arcata at gmail.com
Sun Jan 1 11:41:23 PST 2012


Hi everyone. It looks like, when targeting msvc x86-32 (triple
i?86-pc-win32), Clang still returns all structs by hidden pointer,
although MSVC returns structs sized {8,4,3,2,1} bytes in registers as
documented at http://msdn.microsoft.com/en-us/library/984x0h58.aspx .
A simple test case:

---
#include <stdint.h>

struct Struct1 {
    uint64_t a;
};

struct Struct2 {
    uint32_t a;
};

struct Struct3 {
    char a, b, c;
};

struct Struct1 c_return_1(void) {
    struct Struct1 r = { 0xC1A4C1A4C1A4C1A4ULL };
    return r;
}

struct Struct2 c_return_2(void) {
    struct Struct2 r = { 0xC1A4C1A4U };
    return r;
}

struct Struct3 c_return_3(void) {
    struct Struct3 r = { 0xAA, 0xBB, 0xCC };
    return r;
}
---

cl.exe generates the following asm for c_return_1:

---
_c_return_1 PROC
; File c:\users\joe\documents\code\clay\test\externals\abi\common\external_test1.c
; Line 15
	push	ebp
	mov	ebp, esp
	sub	esp, 8
; Line 16
	mov	DWORD PTR _r$[ebp], -1046167132		; c1a4c1a4H
	mov	DWORD PTR _r$[ebp+4], -1046167132	; c1a4c1a4H
; Line 17
	mov	eax, DWORD PTR _r$[ebp]
	mov	edx, DWORD PTR _r$[ebp+4]
; Line 18
	mov	esp, ebp
	pop	ebp
	ret	0
_c_return_1 ENDP
---

You can see under "Line 17" that it moves the return value into
edx:eax. By contrast, clang expects a hidden pointer argument:

---
_c_return_1:                            # @c_return_1
# BB#0:
	subl	$12, %esp
	movl	16(%esp), %eax
	movsd	L_c_return_1.r, %xmm0
	movsd	%xmm0, (%esp)
	movsd	%xmm0, (%eax)
	addl	$12, %esp
	ret	$4
---

Similar discrepancies occur for c_return_2 and c_return_3.

-Joe



More information about the cfe-dev mailing list