__builtin_unreachable 与 GCC 中的浮点数

Posted

技术标签:

【中文标题】__builtin_unreachable 与 GCC 中的浮点数【英文标题】:__builtin_unreachable with floats in 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 也许吧。我只是好奇为什么会这样。原因很简单。谢谢。 【参考方案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 完全相同。

【讨论】:

以上是关于__builtin_unreachable 与 GCC 中的浮点数的主要内容,如果未能解决你的问题,请参考以下文章

g ++宏连接与c ++宏连接

lag与lead函数 oracle_11g

ojdbc14_g.jar与ojdbc14.jar区别

拉格朗日乘子

安装_oracle11G_客户端_服务端_链接_oracle

拉格朗日乘法与KKT条件