为什么编译器不能优化0浮点加法? [英] Why can the compiler not optimize floating point addition with 0?

查看:84
本文介绍了为什么编译器不能优化0浮点加法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有四个身份函数,它们基本上什么都不做。通过clang只能将 1 的乘法优化为单个 ret 语句。

I have four identity functions which do essentially nothing. Only multiplication with 1 could be optimized by clang to a single ret statement.

float id0(float x) {
    return x + 1 - 1;
}

float id1(float x) {
    return x + 0;
}

float id2(float x) {
    return x * 2 / 2;
}

float id3(float x) {
    return x * 1;
}

以下编译器输出为:(clang 10,处于-O3)

And the following compiler output is: (clang 10, at -O3)

.LCPI0_0:
        .long   1065353216              # float 1
.LCPI0_1:
        .long   3212836864              # float -1
id0(float):                                # @id0(float)
        addss   xmm0, dword ptr [rip + .LCPI0_0]
        addss   xmm0, dword ptr [rip + .LCPI0_1]
        ret
id1(float):                                # @id1(float)
        xorps   xmm1, xmm1
        addss   xmm0, xmm1
        ret
.LCPI2_0:
        .long   1056964608              # float 0.5
id2(float):                                # @id2(float)
        addss   xmm0, xmm0
        mulss   xmm0, dword ptr [rip + .LCPI2_0]
        ret
id3(float):                                # @id3(float)
        ret

I可以理解为什么 id0 id2 无法优化。它们会增加值,然后变成正无穷大,第二个操作不会将其改回。

I can understand why id0 and id2 can't be optimized. They increase the value which could then turn into positive infinity and the second operation would not change it back.

但是为什么不能 id1 是否可以优化?具有无穷大的加法将产生无穷大,具有任何常规数的加法将产生该数,具有 NaN 的加法将产生 NaN 。那么为什么它不是像 * 1 这样的真实身份操作。

But why can't id1 be optimized? Additon with infinity would yield infinity, addition with any regular number would yield that number and addition with NaN would yield NaN. So why is it not a "true" identity operation like * 1.

使用编译器资源管理器的示例

推荐答案

IEEE 754个浮点数具有两个零值,一个负数,一个正数。

IEEE 754 floating-point numbers have two zero values, one negative, one positive. When added together, the result is the positive one.

所以 id1(-0.f) 0.f ,而不是 -0.f

请注意, id1 (-0.f)== -0.f ,因为 0.f == -0.f

So id1(-0.f) is 0.f, not -0.f.
Note that id1(-0.f) == -0.f because 0.f == -0.f.

演示

另外,请注意,在GCC中使用 -ffast-math 进行编译确实可以进行优化并更改结果。

Also, note that compiling with -ffast-math in GCC does make the optimization and changes the result.

这篇关于为什么编译器不能优化0浮点加法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆