https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95886
Bug ID: 95886 Summary: suboptimal memcpy with embedded zero bytes Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- While testing the fix for pr95189 I noticed that the memcpy expansion into copy-by-pieces is less than optimal for sequences containing embedded null bytes. For example, in the test case below, the memcpy call in f() is expanded into what looks like a more efficient sequence than the equivalent memcpy call in g(). The only difference between the two is that the former copies a sequence of non-zero bytes while among the bytes copied by the latter is a null byte. Clang emits the same code for g() as GCC does for f(). $ cat z.c && gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout -o/dev/stdout z.c const char a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; const char b[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; void f (void *d) { __builtin_memcpy (d, a, 9); // optimal } void g (void *d) { __builtin_memcpy (d, b, 9); // suboptimal } .file "z.c" .text ;; Function f (f, funcdef_no=0, decl_uid=1932, cgraph_uid=1, symbol_order=2) f (void * d) { <bb 2> [local count: 1073741824]: __builtin_memcpy (d_2(D), &a, 9); [tail call] return; } .p2align 4 .globl f .type f, @function f: .LFB0: .cfi_startproc movabsq $578437695752307201, %rax movb $9, 8(%rdi) movq %rax, (%rdi) ret .cfi_endproc .LFE0: .size f, .-f ;; Function g (g, funcdef_no=1, decl_uid=1935, cgraph_uid=2, symbol_order=3) g (void * d) { <bb 2> [local count: 1073741824]: __builtin_memcpy (d_2(D), &b, 9); [tail call] return; } .p2align 4 .globl g .type g, @function g: .LFB1: .cfi_startproc movq b(%rip), %rax movq %rax, (%rdi) movzbl b+8(%rip), %eax movb %al, 8(%rdi) ret .cfi_endproc .LFE1: .size g, .-g .globl b .section .rodata .align 8 .type b, @object .size b, 10 b: .string "" .string "\001\002\003\004\005\006\007\b" .globl a .align 8 .type a, @object .size a, 10 a: .string "\001\002\003\004\005\006\007\b\t" .ident "GCC: (GNU) 10.1.1 20200527" .section .note.GNU-stack,"",@progbits