vlad_tepesch
vlad_tepesch

Reputation: 6883

Are compilers allowed to optimize floating point constant multiplication

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

Answers (1)

Pascal Cuoq
Pascal Cuoq

Reputation: 80276

No, it doesn't work

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.

On most architectures, it is not 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.

> would [compilers] also recognize the expression 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

Related Questions