https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105862

            Bug ID: 105862
           Summary: missed inlining opportunity of
                    _Sp_counted_deleter::_M_destroy
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vanyacpp at gmail dot com
  Target Milestone: ---

This sample is reduced from a real usage of shared_ptr.

#include <cstddef>
#include <new>


struct sp_counted_base
{
    sp_counted_base() noexcept
        : use_count(1)
    {}

    virtual void destroy() noexcept
    {}

    void release() noexcept
    {
        if (--use_count == 0)
            destroy();
    }

private:
    sp_counted_base(sp_counted_base const&) = delete;
    sp_counted_base& operator=(sp_counted_base const&) = delete;

    int use_count;
};

struct sp_counted_deleter final : sp_counted_base
{
    virtual void destroy() noexcept
    {
        ::operator delete(this);
    }
};


void test()
{
    sp_counted_deleter* mem = static_cast<sp_counted_deleter*>(::operator
new(sizeof(sp_counted_deleter)));
    ::new (mem) sp_counted_deleter();
    sp_counted_base* pi = mem;
    pi->release();
}

https://godbolt.org/z/dG8h7f1Kn


sp_counted_deleter::destroy():
        jmp     operator delete(void*)
test():
        sub     rsp, 8
        mov     edi, 16
        call    operator new(unsigned long)
        mov     QWORD PTR [rax], OFFSET FLAT:vtable for sp_counted_deleter+16
        mov     rdi, rax
        mov     DWORD PTR [rax+8], 0
        add     rsp, 8
        jmp     sp_counted_deleter::destroy()

In the output assembly the call to sp_counted_deleter::destroy is left
uninlined. I tested the same sample on Clang and it somehow manages to inline
this function. It would be great if GCC was able to inline it too.

Reply via email to