Reputation: 6883
the questionable Code is the following:
float32_t f = someValueFromSomewhere;
f = f * 4;
will compiler optimize this?
According to C-Standard (if i understood it correctly) the second operand has to be promoted to float32_t
;
So the multiplication has to be done using the FPU (or fp emulation).
Theoretically the operation could be done in a normal hardware register by just adding an immediate (and may be overflow checking ). Are compiler allowed to do this optimization? Are there compiler known to do so? And if so, would they also recognize the expression
f = f * 4.0f;
that is required to avoid static code checker warnings about implicit conversions?
Some addition: I know that from the standards point of view both lines are equivalent. But clearly the compiler can distinguish them. So the question is at which time the optimizer is allowed to see the code (or better its internal representation) the first time.
Upvotes: 1
Views: 367
Reputation: 80276
Adding 2 to the exponent in lieu of multiplying by 4.0 only works if the original value is not a subnormal value (including the common zero), is not infinite or NaN, and if the result does not overflow. In general, the compiler does not have this information. When the compiler does have this information, it is allowed to do this transformation, which does not mean that it is a good idea.
Unless you are thinking of a specific execution platform where it would be cheaper to get the value of f
out of the floating-point register it's in, move it into a general-purpose register, add a constant, test special cases (see above), and go back to a floating-point register, you can assume that all these steps are way, way more expensive than a floating-point multiplication. Only if floating-point operations were emulated as series of bit and integer operations would it make sense to “optimize” multiplications by powers of two this way.
f = f * 4.0f;
f * 4
is equivalent to f * (float)4
and thus equivalent to f * 4.0f
. The compiler can transform any of these forms into the same code it would have transformed the other, and any non-toy compiler knows that these are equivalent (for instance as an application of the constant propagation optimization pass to (float)4
).
Upvotes: 6