[llvm-bugs] [Bug 33233] New: [x86] Failing to tail-call memcpy and memmove due to extern C

via llvm-bugs llvm-bugs at lists.llvm.org
Tue May 30 14:54:11 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=33233

            Bug ID: 33233
           Summary: [x86] Failing to tail-call memcpy and memmove due to
                    extern C
           Product: new-bugs
           Version: 4.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: hans at chromium.org
                CC: llvm-bugs at lists.llvm.org
            Blocks: 26299

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, at 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, at function
_Z11libc_memcpyPvPKvj:                  # @_Z11libc_memcpyPvPKvj
        .cfi_startproc
# BB#0:                                 # %entry
        jmp     _Z6memcpyPvPKvj         # TAILCALL
.Lfunc_end0:
[snip]

Beautiful!

Why does extern "C" matter here?


Referenced Bugs:

https://bugs.llvm.org/show_bug.cgi?id=26299
[Bug 26299] [meta][X86] Size optimization opportunities (in particular for
32-bit Chromium on Windows)
-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170530/e17e8865/attachment.html>


More information about the llvm-bugs mailing list