<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [x86] Failing to tail-call memcpy and memmove due to extern C"
href="https://bugs.llvm.org/show_bug.cgi?id=33233">33233</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[x86] Failing to tail-call memcpy and memmove due to extern C
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>4.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>hans@chromium.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Blocks</th>
<td>26299
</td>
</tr></table>
<p>
<div>
<pre>For the following code, we're failing to generate tail calls:
#include <string.h>
void* libc_memcpy(void* dest, const void* src, size_t n) {
return memcpy(dest, src, n);
}
void* libc_memmove(void* dest, const void* src, size_t n) {
return memmove(dest, src, n);
}
$ bin/clang -target i686-unknown-linux-gnu -S -O3 -o - /tmp/a.cc
.text
.file "/tmp/a.cc"
.globl _Z11libc_memcpyPvPKvj # -- Begin function
_Z11libc_memcpyPvPKvj
.p2align 4, 0x90
.type _Z11libc_memcpyPvPKvj,@function
_Z11libc_memcpyPvPKvj: # @_Z11libc_memcpyPvPKvj
# BB#0: # %entry
pushl %esi
subl $8, %esp
movl 16(%esp), %esi
subl $4, %esp
pushl 28(%esp)
pushl 28(%esp)
pushl %esi
calll memcpy
addl $16, %esp
movl %esi, %eax
addl $8, %esp
popl %esi
retl
[snip]
Pretty horrible. Without the header:
#include <stddef.h>
extern "C" {
void* memcpy(void* dest, const void* src, size_t n);
void* memmove(void* dest, const void* src, size_t n);
}
void* libc_memcpy(void* dest, const void* src, size_t n) {
return memcpy(dest, src, n);
}
void* libc_memmove(void* dest, const void* src, size_t n) {
return memmove(dest, src, n);
}
Same thing.
But, if I remove the extern "C":
#include <stddef.h>
void* memcpy(void* dest, const void* src, size_t n);
void* memmove(void* dest, const void* src, size_t n);
void* libc_memcpy(void* dest, const void* src, size_t n) {
return memcpy(dest, src, n);
}
void* libc_memmove(void* dest, const void* src, size_t n) {
return memmove(dest, src, n);
}
$ bin/clang -target i686-unknown-linux-gnu -S -O3 -o - /tmp/a.cc
.text
.file "/tmp/a.cc"
.globl _Z11libc_memcpyPvPKvj # -- Begin function
_Z11libc_memcpyPvPKvj
.p2align 4, 0x90
.type _Z11libc_memcpyPvPKvj,@function
_Z11libc_memcpyPvPKvj: # @_Z11libc_memcpyPvPKvj
.cfi_startproc
# BB#0: # %entry
jmp _Z6memcpyPvPKvj # TAILCALL
.Lfunc_end0:
[snip]
Beautiful!
Why does extern "C" matter here?</pre>
</div>
</p>
<div id="referenced">
<hr style="border: 1px dashed #969696">
<b>Referenced Bugs:</b>
<ul>
<li>
[<a class="bz_bug_link
bz_status_NEW "
title="NEW - [meta][X86] Size optimization opportunities (in particular for 32-bit Chromium on Windows)"
href="https://bugs.llvm.org/show_bug.cgi?id=26299">Bug 26299</a>] [meta][X86] Size optimization opportunities (in particular for 32-bit Chromium on Windows)
</li>
</ul>
</div>
<br>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>