简体   繁体   中英

__builtin_unreachable with floats in GCC

I have the following code, which I am compiling using gcc.

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

When I am using -O3 I get the following assembly .

add:
        addss   xmm0, xmm1
        ret

But with -Ofast I get the following .

add:
        pxor    xmm0, xmm0
        ret

Looks like compiler does understand assume that function is expected to return 0. What does prevent GCC to return 0 as in the second example without -Ofast ?

From GCC documentation :

-fno-signed-zeros
Allow optimizations for floating-point arithmetic that ignore the signedness of zero. IEEE arithmetic specifies the behavior of distinct +0.0 and -0.0 values, which then prohibits simplification of expressions such as x+0.0 or 0.0*x (even with -ffinite-math-only). This option implies that the sign of a zero result isn't significant.

The default is -fsigned-zeros.

-Ofast includes this optimization option, while -O3 doesn't.

Without this option, the function is required to return the exact value of signed zero of the addition result, so the compiler simply perform the addition.

If the 0 is changed to some other value such as 1 or 1.2f or 1.5 , then the compiler will optimize without -ffast-math .

Remark: if the value is changed to 1.2 (so the comparison is the same as static_cast<double>(sum).=1.2 , as required by the standard) then the compiler will keep the addition, although the __builtin_unreachable() will always be executed because there's no float value exactly equal to 1.2 when converted to double.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM