https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110909
Bug ID: 110909 Summary: Suboptimal codegen in vector copy assignment Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: hiraditya at msn dot com Target Milestone: --- #include<vector> using Container = std::vector<int>; int copy_assignment(const Container &v1, Container &v2) { v2 = v1; return 0; } I'd expect this to only generate a memcpy. but i'm not sure why memmoves are generated? $ gcc -std=c++2a -O3 -fno-exceptions copy_assignment(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&): cmp rsi, rdi je .L21 push r13 push r12 push rbp mov rbp, rdi push rbx mov rbx, rsi sub rsp, 8 mov rax, QWORD PTR [rdi+8] mov r13, QWORD PTR [rdi] mov rdx, QWORD PTR [rsi+16] mov rdi, QWORD PTR [rsi] mov r12, rax sub r12, r13 sub rdx, rdi cmp rdx, r12 jb .L25 mov rcx, QWORD PTR [rsi+8] mov rdx, rcx sub rdx, rdi cmp rdx, r12 jnb .L26 cmp rdx, 4 jle .L12 mov rsi, r13 call memmove mov rcx, QWORD PTR [rbx+8] mov rdi, QWORD PTR [rbx] mov rax, QWORD PTR [rbp+8] mov r13, QWORD PTR [rbp+0] mov rdx, rcx sub rdx, rdi .L13: lea rsi, [r13+0+rdx] sub rax, rsi mov rdx, rax cmp rax, 4 jle .L14 mov rdi, rcx call memmove mov rax, QWORD PTR [rbx] add rax, r12 .L8: mov QWORD PTR [rbx+8], rax add rsp, 8 xor eax, eax pop rbx pop rbp pop r12 pop r13 ret .L21: xor eax, eax ret .L25: movabs rax, 9223372036854775804 cmp rax, r12 jb .L27 mov rdi, r12 call operator new(unsigned long) mov rbp, rax cmp r12, 4 jle .L5 mov rdx, r12 mov rsi, r13 mov rdi, rax call memcpy .L6: mov rdi, QWORD PTR [rbx] test rdi, rdi je .L7 mov rsi, QWORD PTR [rbx+16] sub rsi, rdi call operator delete(void*, unsigned long) .L7: lea rax, [rbp+0+r12] mov QWORD PTR [rbx], rbp mov QWORD PTR [rbx+16], rax jmp .L8 .L26: cmp r12, 4 jle .L10 mov rdx, r12 mov rsi, r13 call memmove mov rax, QWORD PTR [rbx] add rax, r12 jmp .L8 .L14: lea rax, [rdi+r12] jne .L8 mov edx, DWORD PTR [rsi] mov DWORD PTR [rcx], edx jmp .L8 .L12: jne .L13 mov esi, DWORD PTR [r13+0] mov DWORD PTR [rdi], esi jmp .L13 .L10: lea rax, [rdi+r12] jne .L8 mov edx, DWORD PTR [r13+0] mov DWORD PTR [rdi], edx jmp .L8 .L5: mov eax, DWORD PTR [r13+0] mov DWORD PTR [rbp+0], eax jmp .L6 .L27: call std::__throw_bad_array_new_length() Ideally, the above C++ code should translate to an equivalent of the following C++ code: using Container = std::vector<int>; int copy_assignment(const Container &v1, Container &v2) { v2.reserve(v1.size()); std::memcpy(&v2[0], &v1[0], v1.size()*sizeof(int)); // change the size: v2.size() = v1.size() return 0; }