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.