Use different LLVM IR functions for unsafe-fp / code gen options

Is there a good way to have different versions of a function in LLVM IR used depending on codegen options/attributes?

Suppose there is bitcode library containing math functions (written in OpenCL). It’s then linked with user bitcode and optimized before codegen. The user code can, for example, invoke the log function and this would expand into different versions of log, based, for example, on unsafe-fp-math flag.

One solution is to have special control functions that return 0 or 1 and are injected (or linked) into IR based on value of LLVM TargetOptions:

float log(float f) {
if (__control_unsafe_fp()) {
unsafe-fp code
} else {
non-unsafe-fp code

However, this seems to assume unsafe-fp attribute is same for all functions globally (it actually seems to be true for OpenCL). In Latest LLVM unsafe-fp-math is attached as function metadata,

I don’t think there is currently a way to overload function (have different versions) in bitcode library based on function attributes/metadata. Any other ways to do the same?

I appreciate any advice or thoughts on how this can be implemented.



Depending on how hacky you want to get, a header containing this would work:

    #ifdef __FAST_MATH__
    #define USE_FAST_VERSION true
    #define USE_FAST_VERSION false
    template<bool Fast> float log(float in);

    #define log(x) log<USE_FAST_VERSION>(x);

I believe that could be made zero-overhead with linker trickery.

Other than that, you'd probably have to modify LLVM to support it. We
already seem to have a "call fast" annotation at the call-site so it'd
be a matter of redirecting the call at CodeGen time to one with a
special name (log$fast_math or something?), likely determined by your