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.