[llvm-dev] -ffast-math optimizations impacted by symbol renaming in header files

Chris Chrulski via llvm-dev llvm-dev at lists.llvm.org
Mon Mar 20 09:27:04 PDT 2017


Hi, 

I came across an issue where some optimizations that would normally be applied to standard math function calls are not getting applied when the –ffast-math option is enabled on the Clang command line on a Linux x86_64 target. 

I tracked down the issue to occurring because the –ffast-math option is triggering Clang to preprocess the math.h header file with the __FINITE_MATH_ONLY__ macro set to 1. In this case, the Linux header files are redirecting several math functions using the __asm__ extension to rename the symbol. An example of what the header files contains is:
      extern double exp (double) __asm__ ("" "__exp_finite") __attribute__ ((__nothrow__ ));

In effect, ‘exp’ gets converted to be ‘__exp_finite’ in the IR. Because some of the optimizations like constant folding or vectorization are looking for the original function name, those optimizations do not get triggered under –ffast-math due to these alternative function names. 

Other affected functions include: acos, asin, exp2, log, log2, log10, and a few others. 

Anybody know if this is intentional, or have input regarding whether these optimizations should be extended to also look for the renamed versions of these functions? 

Thanks,
Chris



A couple of example cases: 

// File: test_folding.c 

// Constant fold will occur with: 
// clang -O2 -S -emit-llvm test_folding.c 

// Constant fold will not occur with: 
// clang -O2 -S -emit-llvm -ffast-math test_folding.c 

#include <math.h> 

double test_fold_exp() { 
  return exp(0.0); 
} 

double test_fold_acos() { 
  return acos(1.0); 
} 

---------------------------------------------- 

// File: test_vectorize.c 

// Vectorization will occur with: 
// clang -O2 -S -emit-llvm -fno-math-errno test_vectorize.c 

// Vectorization will not occur with: 
// clang -O2 -S -emit-llvm -fno-math-errno -ffast-math test_vectorize.c 

#include <math.h> 

void test_vectorize_exp(long n,  float* restrict y,  float* restrict x) { 
  long i; 
  for (i = 0; i < n; i++) { 
    x[i] = expf(y[i]); 
  } 
} 


More information about the llvm-dev mailing list