[LLVMbugs] [Bug 10597] New: When using -mrtd and -ffreestanding, generated memcpy calls get the wrong calling convention
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Sat Aug 6 10:18:53 PDT 2011
http://llvm.org/bugs/show_bug.cgi?id=10597
Summary: When using -mrtd and -ffreestanding, generated memcpy
calls get the wrong calling convention
Product: new-bugs
Version: trunk
Platform: PC
OS/Version: All
Status: NEW
Severity: normal
Priority: P
Component: new bugs
AssignedTo: unassignedbugs at nondot.org
ReportedBy: dimitry at andric.com
CC: llvmbugs at cs.uiuc.edu
When using -mrtd in combination with -ffreestanding, memcpy calls (and
possibly some other builtin function calls) get generated with the wrong
calling convention.
For example, consider the following program (which is meant to get its
memcpy implementation from a separate compilation unit):
//////////////////////////////////////////////////////////////////////
struct foo {
int i[100];
};
void bar(void);
void memcpy(void *dst, const void *src, unsigned len);
void baz(struct foo *x, struct foo *y)
{
bar();
memcpy(x, y, sizeof(struct foo));
bar();
*x = *y; // causes memcpy() to be called
bar();
}
//////////////////////////////////////////////////////////////////////
When you compile this with "-ffreestanding -mrtd", the resulting
assembly for the baz() function becomes:
//////////////////////////////////////////////////////////////////////
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
subl $16, %esp
calll bar
movl 12(%ebp), %esi
movl %esi, 4(%esp)
movl 8(%ebp), %edi
movl %edi, (%esp)
movl $400, 8(%esp) # imm = 0x190
calll memcpy # (1)
subl $12, %esp # (2)
calll bar
movl %esi, 4(%esp)
movl %edi, (%esp)
movl $400, 8(%esp) # imm = 0x190
calll memcpy # (3)
calll bar
addl $16, %esp
popl %esi
popl %edi
popl %ebp
ret $8
//////////////////////////////////////////////////////////////////////
The first call to memcpy (1) is generated correctly, subtracting 12
bytes from the stack (2) to compensate for the 12 bytes that will have
been popped by the body of the memcpy function.
However, the second call to memcpy (3) has been generated by clang
itself, and has been assumed to have cdecl calling convention, even if
-mrtd is on the command line. E.g. "subl $12, %esp" is not inserted
here, and the program will crash more or less spectacularly.
When you look at the corresponding .ll file, you will see:
//////////////////////////////////////////////////////////////////////
tail call x86_stdcallcc void @bar() nounwind optsize
%0 = bitcast %struct.foo* %x to i8*
%1 = bitcast %struct.foo* %y to i8*
tail call x86_stdcallcc void @memcpy(i8* %0, i8* %1, i32 400) nounwind
optsize
tail call x86_stdcallcc void @bar() nounwind optsize
tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 400, i32 4, i1
false)
tail call x86_stdcallcc void @bar() nounwind optsize
//////////////////////////////////////////////////////////////////////
So @llvm.memcpy.p0i8.p0i8.i32 is *not* x86_stdcallcc, and it results in
a cdecl memcpy call in assembly.
(Obviously a workaround is be to explicitly declare memcpy() as cdecl,
but that was impossible until bug 10591 was fixed.)
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list