ConstantFoldFP always calls double version library functions


When llvm does constant folding on a math library function call with constant argument, it seems

the double version of library function is called no matter the original function is single or double

precision. Code can be found in lib/Analysis/ConstantFolding.cpp in various functions like ConstantFoldScalarCall1().

There is a comment that seems explaining why this choice was made:

/// Currently APFloat versions of these functions do not exist, so we use

/// the host native double versions. Float versions are not called

/// directly but for all these it is true (float)(f((double)arg)) ==

/// f(arg). Long double not supported yet.

However we do have a float version exposed by math.h? And the assumption that converting parameter

to double and then converting result back to float gives the same result is not always true. For example

the following code has different result under –O3 (ConstantFoldFP calls log10 at compile time) and –O0 –lm:

#include <math.h>

#include <stdio.h>

int main**()** {

printf**("%.7f\n",** log10f**(0.7177198578332612));**

return 0**;**


Could someone explain to me the current implementation choices of folding library function calls?

Or if let me know if I misunderstood anything. Any help is appreciated.



It’s the same in the sense that “(float)log10((double)x))” is a legal implementation of “log10f(x)”. If you want to actually get the same result that libm would produce at runtime, you can’t constant-fold at all. It’s impossible to predict what libm will produce: the specification is just “some value within a couple ulps of the mathematical result”.

More in-depth discussion on .