[llvm-bugs] [Bug 51000] New: [x86-64] missed optimization: missed tail call in placement-new

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Jul 6 14:18:34 PDT 2021


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

            Bug ID: 51000
           Summary: [x86-64] missed optimization: missed tail call in
                    placement-new
           Product: clang
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: arthur.j.odwyer at gmail.com
                CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
                    neeilans at live.com, richard-llvm at metafoo.co.uk

// https://godbolt.org/z/sqz6eaezs
#include <new>
struct T {
    int x;
    T(int) noexcept;
    ~T();
};
T factory(int) noexcept;
alignas(T) char buffer[sizeof(T)];
void placement_new() {
    ::new ((void*)buffer) T(42);
}
void placement_call() {
    ::new ((void*)buffer) T(factory(42));
}

clang++ -O2 -std=c++20 -emit-llvm test.cpp

The dumped LLVM code for this does correctly have "tail call" in both cases:

  define dso_local void @_Z13placement_newv() local_unnamed_addr #0 !dbg !18 {
    tail call void @_ZN1TC1Ei(%struct.T* nonnull align 4 dereferenceable(4)
bitcast ([4 x i8]* @buffer to %struct.T*), i32 42) #2, !dbg !21
    ret void, !dbg !22
  }
  define dso_local void @_Z14placement_callv() local_unnamed_addr #0 !dbg !23 {
    tail call void @_Z7factoryi(%struct.T* sret(%struct.T) align 4 bitcast ([4
x i8]* @buffer to %struct.T*), i32 42) #2, !dbg !24
    ret void, !dbg !25
  }

However, somewhere between the LLVM code and the backend codegen, the compiler
is failing to generate an actual `jmp` tail call for `placement_call` the way
it's able to for `placement_new`.

  _Z13placement_newv: # @_Z13placement_newv
    movl $buffer, %edi
    movl $42, %esi
    jmp _ZN1TC1Ei # TAILCALL
  _Z14placement_callv: # @_Z14placement_callv
    pushq %rax
    movl $buffer, %edi
    movl $42, %esi
    callq _Z7factoryi
    popq %rax
    retq

Reproduces on x86-64, RISCV-32, RISCV-64, ARMv7-a. So it's somehow happening
after -emit-llvm, but not backend-arch-specific??

Note that right now GCC has the same symptom; but ICC and MSVC both get this
right and generate tail-calls appropriately in both cases. So this isn't any
obscure C++ corner case AFAICT; seems it's truly just a missed optimization.

Some other (possibly related) missed-tail-call bugs: PR50138, PR48508, PR45591,
PR13826.

-- 
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/20210706/31cf0c05/attachment-0001.html>


More information about the llvm-bugs mailing list