https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93528
Bug ID: 93528 Summary: Object copy not optimized out for most sizes in strict aliasing memcpy pattern Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: andrey.vihrov at gmail dot com Target Milestone: --- Host: x86_64-pc-linux-gnu Target: x86_64-pc-linux-gnu Consider the following code (a common pattern to avoid strict aliasing violations): struct X { char arr[10]; }; void foo(void *p) { X x; memcpy(&x, p, sizeof(x)); x.arr[0] = 42; memcpy(p, &x, sizeof(x)); } When the array is 1, 2, 4, 8 or 16 elements long, memcpy() is optimized out with -O2. Output for x86-64 Linux: _Z3fooPv: movb $42, (%rdi) ret For other struct sizes, copies are performed nonetheless. Depending on the array size either an inline implementation or a call to memcpy() is inserted. For the above case, on x86-64 Linux GCC generates _Z3fooPv: movq (%rdi), %rax movq %rax, -10(%rsp) movb $42, -10(%rsp) movq -10(%rsp), %rax movq %rax, (%rdi) ret It seems that the field types and the layout of the struct don't matter, and the optimization is conditional on object size only. For example, struct Y { int a, b, c; }; is affected as well. As a variant, the problem also appears with a plain array instead of a struct: void bar(void *p) { int arr[3]; memcpy(arr, p, sizeof(arr)); arr[0] = 42; memcpy(p, arr, sizeof(arr)); } gives _Z3barPv: movq (%rdi), %rax movq %rax, -12(%rsp) movl $42, -12(%rsp) movq -12(%rsp), %rax movq %rax, (%rdi) ret