Just extract the value and cast to Constant:

auto Callee = F.getParent()->getOrInsertFunction("_ly_fun_b", type);
auto Fun = dyn_cast<Constant>(Callee.getCallee());
Answer from yugr on Stack Overflow
🌐
LLVM
llvm.org › doxygen › classllvm_1_1FunctionCallee.html
LLVM: llvm::FunctionCallee Class Reference
llvm · FunctionCallee · Public Member Functions | List of all members · llvm::FunctionCallee Class Reference · A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single entity. More... #include "llvm/IR/DerivedTypes.h" A handy container for a ...
🌐
LLVM
llvm.org › doxygen › classllvm_1_1Module.html
LLVM: llvm::Module Class Reference
References llvm::FunctionType::get(), and getOrInsertFunction(). Definition at line 228 of file Module.cpp. Look up the specified function in the module symbol table. If it does not exist, add a prototype for the function and return it. Otherwise, return the existing function. In all cases, the returned value is a FunctionCallee wrapper around the 'FunctionType T' passed in, as well as the 'Value' of the Function.
🌐
LLVM
llvm.org › doxygen › classllvm_1_1FunctionCallee-members.html
FunctionCallee Member List
This is the complete list of members for llvm::FunctionCallee, including all inherited members.
🌐
Hdoc
docs.hdoc.io › hdoc › llvm-project › rD241AEB7BC9E92EB.html
class FunctionCallee: LLVM/Clang 15.x documentation - hdoc
private llvm::Value* Callee = nullptr · public FunctionCallee(llvm::FunctionType * FnTy, llvm::Value * Callee) public FunctionCallee(std::nullptr_t) public FunctionCallee() public template <typename T, typename U = decltype(& T::getFunctionType)> FunctionCallee(T * Fn) public llvm::Value * getCallee() public llvm::FunctionType * getFunctionType() public bool operator bool() Declared at: llvm/include/llvm/IR/DerivedTypes.h:173 ·
🌐
LLVM Discussion Forums
discourse.llvm.org › beginners
Confused about Function vs FunctionCallee, etc - Beginners - LLVM Discussion Forums
June 23, 2023 - I’m confused by Function and FunctionCallee semantics. Why is FunctionCallee a {Value, FunctionType} pair and not a {Function, FunctionType} pair? Can the Value sometimes be something other than a Function? IRBuilder has CreateCall() flavours taking a FunctionCallee and a Function.
🌐
LLVM
llvm.org › doxygen › classllvm_1_1CallInst.html
LLVM: llvm::CallInst Class Reference
This class represents a function call, abstracting a target machine's calling convention. More · This class represents a function call, abstracting a target machine's calling convention
🌐
Google Groups
groups.google.com › g › llvm-dev › c › eF6VF0_afmg › m › 5DzxtE0tDAAJ
[llvm-dev] Finding callees of a function
So something like: > > for (auto &U : F.getUsers()) { > if (auto CS = CallSite(U)) { > if (CS->getCalledFunction() == F) > doStuff(CS); > } > } Nit: This might visit the same call site multiple times if the function is passed as a function pointer argument to recursive call `f(&f, &f)`. for (auto &U : F.getUses()) { if (auto CS = CallSite(U.getUser())) { if (CS->isCallee(&U)) doStuff(CS); } } or, if you also want to deal with callback calls [0, 1, 2], you can do: for (auto &U : F.getUses()) { if (auto ACS = AbstractCallSite(U)) doStuff(ACS); // or ACS.getCallSite() } Cheers, Johannes [0] https://clang.llvm.org/docs/AttributeReference.html#callback [1] https://llvm.org/docs/LangRef.html#callback-metadata [2] https://www.youtube.com/watch?v=zfiHaPaoQPc
🌐
LLVM
llvm.org › doxygen › BuildLibCalls_8cpp_source.html
LLVM: lib/Transforms/Utils/BuildLibCalls.cpp Source File
1537 FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType); 1538 inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI); 1539 CallInst *CI = B.CreateCall(Callee, Operands, FuncName); 1540 if (const Function *F = 1541 dyn_cast<Function>(Callee.getCallee()->stripPointerCasts())) 1542 CI->setCallingConv(F->getCallingConv()); 1543 return CI; 1544} 1545 · 1546Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL, 1547 const TargetLibraryInfo *TLI) { 1548 Type *CharPtrTy = B.getPtrTy(); 1549 Type *SizeTTy = getSizeTTy(B, TLI); 1550 return emitLibCall(LibFunc_strlen, SizeTTy, CharPtrTy, Ptr, B, TLI); 1551} 1552 ·
Find elsewhere
🌐
LLVM
reviews.llvm.org › D57315
⚙ D57315 [opaque pointer types] Add a FunctionCallee wrapper type, and use it.
January 27, 2019 - The FunctionCallee type is effectively a {FunctionType*,Value*} pair, and is a useful convenience to enable code to continue passing the result of getOrInsertFunction() through to EmitCall, even once pointer types lose their pointee-type · One area of particular note is the change to the sanitizer ...
🌐
LLVM
llvm.org › doxygen › classllvm_1_1CallBase.html
LLVM: llvm::CallBase Class Reference
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to calling a function. More · These methods access and modify attributes on this call (including looking through to the attributes on the called function when necessary)
🌐
GitHub
github.com › sampsyo › llvm-pass-skeleton › issues › 19
Error while making rtlib example · Issue #19 · sampsyo/llvm-pass-skeleton
June 5, 2019 - Scanning dependencies of target SkeletonPass [ 50%] Building CXX object skeleton/CMakeFiles/SkeletonPass.dir/Skeleton.cpp.o /llvm-pass-skeleton/skeleton/Skeleton.cpp: In member function ‘virtual bool {anonymous}::SkeletonPass::runOnFunction(llvm::Function&)’: /llvm-pass-skeleton/skeleton/Skeleton.cpp:23:84: error: cannot convert ‘llvm::FunctionCallee’ to ‘llvm::Constant*’ in initialization Constant *logFunc = F.getParent()->getOrInsertFunction("logop", logFuncType); ^ skeleton/CMakeFiles/SkeletonPass.dir/build.make:62: recipe for target 'skeleton/CMakeFiles/SkeletonPass.dir/Skeleto
Author   sampsyo
🌐
LLVM
llvm.org › doxygen › DerivedTypes_8h_source.html
LLVM: include/llvm/IR/DerivedTypes.h Source File
llvm::FunctionCallee::getCallee · Value * getCallee() Definition DerivedTypes.h:189 · llvm::FunctionCallee::FunctionCallee · FunctionCallee()=default · llvm::FunctionCallee::FunctionCallee · FunctionCallee(FunctionType *FnTy, Value *Callee) Definition DerivedTypes.h:178 ·
🌐
FreeDesktop
bugs.freedesktop.org › show_bug.cgi
109540 – gen_builder_meta.hpp:51:117: error: no matching function for call to ‘cast(llvm::FunctionCallee)’
March 23, 2019 - Bugzilla – Bug 109540 gen_builder_meta.hpp:51:117: error: no matching function for call to ‘cast(llvm::FunctionCallee)’ Last modified: 2019-03-23 01:46:10 UTC
🌐
GitHub
github.com › imageworks › OpenShadingLanguage › issues › 1052
Build fails with llvm9.0-rc2 · Issue #1052 · AcademySoftwareFoundation/OpenShadingLanguage
August 22, 2019 - .../OpenShadingLanguage-Release-1.10.6/src/liboslexec/llvm_util.cpp:689:21: error: no viable conversion from 'llvm::FunctionCallee' to 'llvm::Constant *' llvm::Constant *c = module()->getOrInsertFunction (name, functype); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated.
Author   AcademySoftwareFoundation
🌐
GitHub
github.com › llvm-mirror › clang › blob › master › lib › CodeGen › CodeGenModule.h
clang/lib/CodeGen/CodeGenModule.h at master · llvm-mirror/clang
April 23, 2020 - llvm::FunctionCallee objc_alloc; · /// void objc_allocWithZone(id); llvm::FunctionCallee objc_allocWithZone; · /// void objc_alloc_init(id); llvm::FunctionCallee objc_alloc_init; · /// void objc_autoreleasePoolPop(void*); llvm::FunctionCallee objc_autoreleasePoolPop; ·
Author   llvm-mirror
Top answer
1 of 2
1

I was struggling with something similar. My toy program is equivalent to the following C program, but generating the function boo() at run time:

#include <stdio.h>
typedef int (*callback)(const char*);
static int boo(callback print, const char *str) { return print(str); }
int main() { return boo(puts, "hello world"); }

I believe that my solution should work at least with LLVM 9 through 14, based on testing with those two versions.

#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

int main()
{
  llvm::InitializeNativeTarget();
  llvm::InitializeNativeTargetAsmPrinter();

  auto C = std::make_unique<llvm::LLVMContext>();
  auto M = std::make_unique<llvm::Module>("boomodule", *C);

  const auto ArgType = llvm::Type::getInt8Ty(*C)->getPointerTo();
  std::vector<llvm::Type *> PutsArgs{ArgType};
  llvm::FunctionType *PutsType =
    llvm::FunctionType::get(llvm::Type::getInt32Ty(*C), PutsArgs, false);
  llvm::FunctionType *FT =
    llvm::FunctionType::get(llvm::Type::getInt32Ty(*C),
                            {PutsType->getPointerTo(), ArgType}, false);

  {
    llvm::Function *TheFunction =
      llvm::Function::Create(FT, llvm::Function::ExternalLinkage,
                             "boo", M.get());
    {
      llvm::IRBuilder<> builder(llvm::BasicBlock::Create(*C, "entry",
                                                         TheFunction));
      auto Arg = TheFunction->arg_begin();
      llvm::FunctionCallee FC{PutsType, Arg++};
      builder.CreateRet(builder.CreateCall(FC, Arg));
    }
    assert(!llvm::verifyFunction(*TheFunction, &llvm::errs()));
    // TheFunction->dump();
  }

  llvm::ExitOnError ExitOnErr;
  auto J = ExitOnErr(llvm::orc::LLJITBuilder().create());
  ExitOnErr(J->addIRModule
            (llvm::orc::ThreadSafeModule(std::move(M), std::move(C))));
  auto BooAddr = ExitOnErr(J->lookup("boo"));
  typedef int (*callback)(const char*);
  auto boo =
    reinterpret_cast<int(*)(callback, const char*)>(BooAddr.getAddress());
  return boo(puts, "hello world");
}
// c++ lljit.cc $(llvm-config --cxxflags --ldflags --system-libs --libs core)

I found some other example where CreateAlloca() was used for storing and loading a function pointer. In my intended application, I will be passing an array of function pointers via a parameter to the generated function.

2 of 2
0

(I understood your question as: I have a C++ pointer to a LLVM function and I need to create a call to it, if I got it wrong please clarify it in the post or in the comments below)

Most of LLVM classes derive from llvm::Value, when you do something like

llvm::Function *theFunction = llvm::Function::Create(...);

llvm::Function is a subclass of llvm::Value and you can use it in a CreateCall

Value *result = Builder.CreateCall(theFunction, ...); // This is the call instruction
🌐
LLVM
llvm.org › doxygen › classllvm_1_1Function.html
LLVM: llvm::Function Class Reference
Referenced by llvm::OpenMPIRBuilder::addAttributes(), llvm::X86FrameLowering::adjustForHiPEPrologue(), arg_empty(), CC_X86_Intr(), llvm::Attributor::checkForAllCallSites(), llvm::CloneFunctionAttributesInto(), createSwitchStatement(), llvm::OpenMPIRBuilder::createTargetInit(), createTargetParallelWrapper(), llvm::OpenMPIRBuilder::createTeams(), llvm::X86FrameLowering::emitPrologue(), findArgumentCopyElisionCandidates(), llvm::IRPosition::getAssociatedArgument(), llvm::IRPosition::getNumArgs(), llvm::instrumentor::FunctionIO::getNumArguments(), hasSameArgumentList(), hostParallelCallback(), llvm::Attributor::isValidFunctionSignatureRewrite(), LLVMGetNextParam(), llvm::VPlanTransforms::makeCallWideningDecisions(), llvm::Attributor::registerFunctionSignatureRewrite(), replaceCalledFunction(), llvm::CoroAnnotationElidePass::run(), targetParallelCallback(), and upgradeNVVMIntrinsicCall().
🌐
LLVM
llvm.org › doxygen › classllvm_1_1InvokeInst.html
LLVM: llvm::InvokeInst Class Reference
private: llvm::BasicBlock *BB; llvm::BasicBlock::iterator It; Context *Ctx; LLVM_ABI pointer getInstr(llvm::BasicBlock::iterator It) const;
🌐
GitHub
github.com › intel › intel-graphics-compiler › issues › 59
IGC build errors against LLVM-9 · Issue #59 · intel/intel-graphics-compiler
February 12, 2019 - /home/dvrogozh/git/github/tmp/igc/IGC/GenISAIntrinsics/GenIntrinsics.cpp:519:83: error: no matching function for call to ‘cast<llvm::Function>(llvm::FunctionCallee)’ /home/dvrogozh/git/github/tmp/igc/IGC/Compiler/CISACodeGen/ResolveGAS.cpp:595:14: error: cannot convert ‘llvm::Functio...
Author   intel