4

我想知道 GCC 是否会使用我创建的结构过度对齐的知识,并在生成比较 asm 时将其简单地视为一个整数。

它不是。我想知道这是否是由于 ABI 问题,我错过了其他一些因素,还是真的缺少优化?

螺栓链接

代码:

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);
4

1 回答 1

3

这很可能是错过的优化。仅用default手动实现替换 ed 比较运算符会导致在过度对齐的结构版本中输出 32 位比较。即这个

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;
}

结果是:

f4(S4 const&):
        mov     eax, DWORD PTR [rdi]
        cmp     DWORD PTR f4(S4 const&)::c[rip], eax
        sete    al
        ret

在这个版本中显然遗漏了另一个优化(将c直接操作数设为 yield cmp eax, 0x16000b),但至少没有单独的 16 位比较。

使用您的两个版本和两个手动定义的运算符查看完整的游乐场。

于 2019-12-23T20:27:42.483 回答