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.