I am building an IR module using the IRBuilder, and I want to be able to call libc functions from inside this module (For the most part math functions like atan that don't have intrinsics).
I think I need to add them using getOrInsertLibFunc , is that correct? This requires me to have a TargetLibraryInfo instance.
How do I obtain one, and is there an example anywhere that inserts the library function and shows how to create a call to it using the IRBuilder?
Note that I know how to create an external link to the std::atan function that is available in C++, but I specifically want to insert a llvm::LibFunc since I think the LLVM function passes are better able to reason about its behaviour.
(Interestingly, the function passes I use will convert a sin(x)/cos(x) (intrinsics) to a tan(x), but I don't know how insert tan (not an intrinsic) myself.)
Edit: I got the following to work ("data" is just my own struct where I keep around pointers):
auto triple = llvm::sys::getDefaultTargetTriple();
data->libinfoimpl = std::make_unique<llvm::TargetLibraryInfoImpl>(llvm::Triple(triple));
data->libinfo = std::make_unique<llvm::TargetLibraryInfo>(*data->libinfoimpl);
auto doubleTy = llvm::Type::getDoubleTy(*data->context);
llvm::FunctionType *fun_type = llvm::FunctionType::get(doubleTy, {doubleTy}, false);
llvm::getOrInsertLibFunc(data->module.get(), *data->libinfo, llvm::LibFunc_tan, fun_type);
And insert the function call using
auto fun = data->module->getFunction("tan");
result = data->builder->CreateCall(fun, arg);
Not sure if this is the ideal way to do it, but it works. If anybody knows a better way, please let me know!
Edit again: I have a follow-up question: If I create a call to tan(atan(x)) the optimizer knows that it should just return x, but for some reason it still creates the call to atan() (but not to tan). Why does this happen, and can I make it not call atan? Example:
%res = tail call fast double @atan(double %arg)
store double %arg, ptr %state_vars, align 8
I.e. it calls atan on arg, but it does not use the result %res, so why wasn't that call optimized away?