https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121146
Bug ID: 121146
Summary: memcpy does not recognize alignas
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: rockeet at gmail dot com
Target Milestone: ---
#include <string.h>
#include <utility>
#define extent(a) sizeof(a)/sizeof(a[0])
struct alignas(16) B {
int a[12];
};
void B_swap1(B* x, B* y) {
B t;
memcpy(&t, x, sizeof(B));
memcpy( x, y, sizeof(B));
memcpy( y, &t, sizeof(B));
}
void B_swap2(B* x, B* y) {
for (int i = 0; i < extent(x->a); i++) {
std::swap(x->a[i], y->a[i]);
}
}
B_swap1 and B_swap2 should generate same code, B_swap2 generates ideal movdqa,
but B_swap1 generates movdqu:
B_swap1(B*, B*):
movdqu xmm3, XMMWORD PTR [rsi]
movdqu xmm2, XMMWORD PTR [rdi]
movdqu xmm1, XMMWORD PTR [rdi+16]
movdqu xmm0, XMMWORD PTR [rdi+32]
movups XMMWORD PTR [rdi], xmm3
movdqu xmm3, XMMWORD PTR [rsi+16]
movups XMMWORD PTR [rdi+16], xmm3
movdqu xmm3, XMMWORD PTR [rsi+32]
movups XMMWORD PTR [rdi+32], xmm3
movups XMMWORD PTR [rsi], xmm2
movups XMMWORD PTR [rsi+16], xmm1
movups XMMWORD PTR [rsi+32], xmm0
ret
B_swap2(B*, B*):
movdqa xmm0, XMMWORD PTR [rdi]
movdqa xmm1, XMMWORD PTR [rsi]
movaps XMMWORD PTR [rdi], xmm1
movdqa xmm1, XMMWORD PTR [rsi+16]
movaps XMMWORD PTR [rsi], xmm0
movdqa xmm0, XMMWORD PTR [rdi+16]
movaps XMMWORD PTR [rdi+16], xmm1
movdqa xmm1, XMMWORD PTR [rsi+32]
movaps XMMWORD PTR [rsi+16], xmm0
movdqa xmm0, XMMWORD PTR [rdi+32]
movaps XMMWORD PTR [rdi+32], xmm1
movaps XMMWORD PTR [rsi+32], xmm0
ret
This is better than clang, but B_swap1 should be better -- same with B_swap2.