I can call a C++ function from a JITed LLVM function: I use clang to compile the C++ function into LLVM IR, and then I peek at its LLVM type. For example, a std::array<uint64_t, 2>(*)()
type in C++ becomes a function returning {i64, i64}
in LLVM IR. Then, I can create an appropriate FunctionType, and call my desired function.
But in the opposite direction, if I have a LLVM function that returns [i64 x 3]
, how do I call this function from C++ code? I tried casting the returned function pointer to (std::array<uint64_t, 3>(*)())
, and then calling it, but it's clear this is not working because the return values don't show up when I try to print them. Ideally, I'd like my C++ code to be able to call any function that returns [i64 x N]
, for arbitrary N >= 2.
/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp has a mild attempt at handling function return types, but it bails on the cases I'm interested in. (it says, "Full-featured argument passing not supported yet!")
It's not possible with pure C++. According to Returning structs in registers - ARM ABI in GCC, ABI matters can't be handled without assembly. Empirically, I see that on Linux x64, the LLVM IR convention is that up to three return integers are returned in the eax, edx, ecx registers, and then 4-or-more are returned in memory. In C++, it's only possible to return a single object in registers; larger objects must go in a struct, which must then be returned in memory.