【问题标题】:__builtin_unreachable with floats in GCC__builtin_unreachable 与 GCC 中的浮点数
【发布时间】:2020-12-30 01:51:33
【问题描述】:

我有以下代码,我正在使用 gcc 进行编译。

float add(float a, float b) {
    float sum = a + b;
    if (sum != 0) __builtin_unreachable();
    return sum;
}

当我使用-O3 时,我得到following assembly

add:
        addss   xmm0, xmm1
        ret

但是-Ofast 我得到了following

add:
        pxor    xmm0, xmm0
        ret

看起来编译器确实理解假设函数应该返回 0。是什么阻止了 GCC 在没有 -Ofast 的情况下返回 0 的第二个示例?

【问题讨论】:

  • 负零? -
  • @user202729 哈哈。你说的对。它适用于 1。谢谢。
  • 虽然我觉得基于 unreachable 的值优化并没有得到很好的支持(因为在大多数实际程序中你不能从中得到太多?)。
  • @user202729 也许吧。我只是好奇为什么会这样。原因很简单。谢谢。

标签: c++ c gcc


【解决方案1】:

来自GCC documentation

-fno-signed-zeros
允许对忽略零符号的浮点算术进行优化。 IEEE 算术指定不同 +0.0 和 -0.0 值的行为,然后禁止简化表达式,例如 x+0.0 或 0.0*x(即使使用 -ffinite-math-only)。此选项意味着零结果的符号不重要。

默认为 -fsigned-zeros。

-Ofast 包含此优化选项,而-O3 不包含。

如果没有这个选项,函数需要返回加法结果的有符号零的确切值,所以编译器只执行加法。

如果将0 更改为其他值,例如11.2f1.5,则编译器将在不使用-ffast-math 的情况下进行优化。

备注:如果将值更改为1.2(因此比较与static_cast<double>(sum)!=1.2相同,按标准要求),则编译器将保留加法,尽管__builtin_unreachable()将始终执行,因为转换为双精度时,没有 float 值与 1.2 完全相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多