【问题标题】:Missed optimization in clang only on powers of two仅在 2 次方上错过了 clang 中的优化
【发布时间】:2019-10-18 09:10:18
【问题描述】:

使用 -Ofast 编译时,clang 正确推断出以下函数将始终返回 0。

int zero(bool b) {
    const int x = 5;
    return (x * b) + (-x * b);
}

编译成

zero(bool):                               # @zero(bool)
        xor     eax, eax
        ret

但是,如果我将常数更改为 2 的任意幂(1 或 0 除外),clang 不再进行相同的扣除

int zero(bool b) {
    const int x = 8;
    return (x * b) + (-x * b);
}

编译成

zero(bool):                               # @zero(bool)
        mov     eax, edi
        shl     eax, 3
        xor     dil, 1
        movzx   ecx, dil
        lea     eax, [rax + 8*rcx]
        add     eax, -8
        ret

The code compiled with compiler explorer.

如果我将函数参数更改为更大(short、int、long),则优化正确。

是什么导致了这种奇怪的边缘情况?

【问题讨论】:

  • 为它记录一个错误?
  • 并且如果把常量改成传递给函数的参数,代码是正确的。确实很奇怪。
  • @AlainMerigot 很好的观察,我没有注意到。它还可以在 2**31 再次工作,甚至通过使常量无符号来防止溢出。
  • 很好的错误报告。不必要的 Stack Overflow 问题。
  • @WernerHenze 我不同意。 “为什么会发生这种情况”的问题尚未得到解答。

标签: c++ x86 clang compiler-optimization


【解决方案1】:

即使一元减号运算符是默认值,编译器似乎也不执行算术否定。它没有义务这样做。

【讨论】:

    猜你喜欢
    • 2020-12-14
    • 2012-12-05
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 2016-02-07
    • 2013-03-10
    相关资源
    最近更新 更多