[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