I'm working on some code that uses the LLVM C API. How do I use intrinsics, such as llvm.cos.f64
or llvm.sadd.with.overflow.i32
? Whenever I try to do it by generating a global with LLVMAddGlobal
(with the correct type signature), I just get this error message during the JIT linking stage:
LLVM ERROR: Could not resolve external global address: llvm.cos.f64
I'm not using the LLVM C++ interface, so the advice in LLVM insert intrinsic function Cos does not seem to apply.
I presume I need something like Intrinsic::getDeclaration
, but I can't seem to find it. Am I missing something obvious?
I've now resolved this by writing a short piece of C++ code that calls the API I referenced in the other question,
llvm::Intrinsic::getDeclaration
, and I use a little magic to get the list of legal intrinsics. I'd have rather done this with a pure C API, but my need for making things work is stronger than my need for strict language purity.To get the list of names of intrinsics, I do this:
This produces a sorted table, so I can use
bsearch
to find the ID that I want.To get the actual intrinsic that I can then call, I do this (which requires a module reference and an argument type reference):
That
LLVMValueRef
is suitable for use with the rest of the LLVM C API. The key is that I'm usingllvm::unwrap
andllvm::wrap
.No need to leave the C API. Pass the intrinsic name to
LLVMAddFunction
:Then you can generate a call to
fn
withLLVMBuildCall
.