https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68350
--- Comment #16 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Barry Revzin from comment #8) > Whereas the copy_b case could also use memmove. Or memcpy even, because std::uninitialized_copy requires the ranges to be non-overlapping, whereas std::copy only requires With the patch I'm testing I get identical codegen for copy_a and copy_b: _Z6copy_bP1BS0_S0_: .LFB3321: .cfi_startproc subq %rdi, %rsi movq %rdx, %rax movq %rsi, %rdx cmpq $4, %rsi jle .L7 movq %rdi, %rsi movq %rax, %rdi jmp memcpy .p2align 4,,10 .p2align 3 .L7: je .L9 ret .p2align 4,,10 .p2align 3 .L9: movl (%rdi), %edx movl %edx, (%rax) ret .cfi_endproc It got worse than the original results shown in comment 8 because of the fix for PR 108846. We can't use memcpy when std::distance(first, last) == 1 because it could overwrite tail padding that would not be affected by using std::construct_at as specified in the standard. But at least it's consistently worse for copy_a and copy_b.