I was wondering if GCC will use the knowledge that the struct I created is overaligned and consider it simply as an integer when it comes to the generation of comparison asm.
It does not. I wonder if this is due to ABI issues, some other factor I missed or is it really a missing optimization?
code:
struct S{
short a,b;
bool operator == (const S&) const = default;
};
struct alignas(alignof(int)) S2 {
short a,b;
bool operator == (const S2&) const = default;
};
bool f(const S& s){
constinit static S c{11,22};
return c==s;
}
bool f2(const S2& s2){
constinit static S2 c2{11,22};
return c2==s2;
}
static_assert(alignof(S)==2);
static_assert(alignof(S2)==4);
It's most likely a missed optimization. A mere replacement of the default
ed comparison operator with a manual implementation results in 32-bit comparison being output in the overaligned struct version. I.e. this
struct alignas(alignof(int)) S4
{
short a,b;
bool operator == (const S4& s) const { return a==s.a && b==s.b; }
};
bool f4(const S4& s)
{
constinit static S4 c{11,22};
return c==s;
}
results in this:
f4(S4 const&):
mov eax, DWORD PTR [rdi]
cmp DWORD PTR f4(S4 const&)::c[rip], eax
sete al
ret
Another optimization is obviously missed in this version (making c
an immediate operand to yield cmp eax, 0x16000b
), but at least there's no separate 16-bit comparisons.
See the full playground with your two versions and two with manually-defined operators.