为什么't GCC能为两个int32的结构生成一个最优运算符==?

2021-02-19 11:51

一位同事向我展示了我认为不必要的代码,但确实如此。我希望大多数编译器都会把这三种平等测试的尝试看作是e等效:#包括gt;#includegt;结构点{std::int32\u t

解答动态

  • (a.y^b.y))==0;} GCC和clang在按值传递结构时都有相同的遗漏优化(因此a在RDI中,b在RSI中,因为x86-64 systemv的调用约定就是这样将结构打包到寄存器的):https://godbolt.org/z/v88a6s。memcpy/memcmp版本都编译成cmp rdi,rsi/sete al,但是其他的操作是的32位操作。
    struct alignas(uint64\u t)Point在参数位于寄存器中的按值情况下仍然有帮助,优化了GCC的两个相同版本,但没有优化bithack XOR/OR。(https://godbolt.org/z/ofGa1f). 这能给我们一些关于GCC内部的提示吗?对齐对clang没有帮助。

    • 如果您“修复”了对齐,那么所有这些都会给出相同的a(使用gcc):
      struct alignas(alignof(std::int64

      • t))Point{std::int32

        • t x,y;}; Demo

          • 为什么编译器不能生成[与memcpy版本相同的程序集]?
            编译器“可以”在允许的意义上。
            编译器根本没有。为什么没有超出我的知识范围,因为这需要深入了解优化程序是如何实现的。但是,答案可能从“没有覆盖这种转换的逻辑”到“规则没有调整为假设一个输出比另一个快”。
            如果使用Clang而不是GCC,您会注意到它为Equal和Equal1生成相同的输出,并且程序集没有跳转。除了使用两条32位指令代替一条64位指令外,它与“优化”版本相同。此外,如Jarod42的答案所示,点的对齐对优化者没有影响。
            MSVC的行为就像叮当声,因为它不受对齐的影响,但不同的是,它没有摆脱跳跃。
            就其价值而言,编译器(我检查了GCC和Clang)产生了与C++ 20默认比较基本相同的输出,因为它们是相等的。不管出于什么原因,GCC选择使用jne而不是je来进行跳转。
            这是一个缺少的编译器优化
            ,假设在目标cpu上一个总是比另一个快,这是一个公平的结论。

            • End

            免责声明:

            本页内容仅代表作者本人意见,若因此产生任何纠纷由作者本人负责,概与琴岛网公司无关。本页内容仅供参考,请您根据自身实际情况谨慎操作。尤其涉及您或第三方利益等事项,请咨询专业人士处理。