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

            Bug ID: 124121
           Summary: Missed optimization in initialization of
                    std::inplace_vector with std::initializer_list
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: janschultke at googlemail dot com
  Target Milestone: ---

Consider the following example (https://compiler-explorer.com/z/qTjGh3rP8):

#include <inplace_vector>
std::inplace_vector<char, 4> f() {
  return {'a', 'b', 'c'};
}
std::inplace_vector<char, 4> g() {
  constexpr std::inplace_vector<char, 4> result{'a', 'b', 'c'};
  return result;
}

GCC compiles this to:

"f()":
        lea     rax, [rsp-10]
        mov     DWORD PTR [rsp-10], 0
        mov     BYTE PTR [rsp-6], 0
        movzx   eax, WORD PTR "C.0.0"[rip]
        movabs  rdx, 12884901888
        mov     WORD PTR [rsp-10], ax
        movzx   eax, BYTE PTR "C.0.0"[rip+2]
        mov     BYTE PTR [rsp-8], al
        mov     eax, DWORD PTR [rsp-10]
        or      rax, rdx
        ret
"g()":
        movabs  rax, 12891415137
        ret
"C.0.0":
        .byte   97
        .byte   98
        .byte   99
        .zero   1

Clang with libstdc++ compiles this to:

f():
        mov     byte ptr [rsp - 12], 0
        lea     rax, [rsp - 16]
        mov     qword ptr [rsp - 8], rax
        mov     word ptr [rsp - 16], 25185
        mov     byte ptr [rsp - 14], 99
        mov     byte ptr [rsp - 12], 3
        mov     ecx, dword ptr [rsp - 16]
        movabs  rax, 12884901888
        or      rax, rcx
        ret

g():
        movabs  rax, 12891415137
        ret

Note that 12891415137 = 0x00000003'00636261.

Not to nitpick every instruction, but something is seriously going wrong here.
This code is essentially returning a single-register constant, and all of that
gunk should be easily inlinable.
There is no reason why f should optimize any worse than g.

See
https://github.com/gcc-mirror/gcc/blob/642020ab7e5ba659a626a0808347e0488ae69394/libstdc%2B%2B-v3/include/std/inplace_vector#L124-L131
for constructor code.

Reply via email to