__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
更改为其他值,例如1
或1.2f
或1.5
,则编译器将在不使用-ffast-math
的情况下进行优化。
备注:如果将值更改为1.2
(因此比较与static_cast<double>(sum)!=1.2
相同,按标准要求),则编译器将保留加法,尽管__builtin_unreachable()
将始终执行,因为转换为双精度时,没有 float
值与 1.2
完全相同。
【讨论】:
以上是关于__builtin_unreachable 与 GCC 中的浮点数的主要内容,如果未能解决你的问题,请参考以下文章