Hi, I'm attempting to use MCJIT with the C interface with llvm-3.9.0, and it doesn't seem to work. This code is derived from Paul Smith's example code: int main(int argc, char const* argv[]) { LLVMModuleRef mod = LLVMModuleCreateWithName("my_module"); LLVMTypeRef param_types[] = {LLVMInt32Type(), LLVMInt32Type()}; LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, 0); LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type); LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry"); LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, entry); LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp"); LLVMBuildRet(builder, tmp); char* error = NULL; LLVMVerifyModule(mod, LLVMAbortProcessAction, &error); LLVMDisposeMessage(error); LLVMExecutionEngineRef engine; error = NULL; LLVMLinkInMCJIT(); LLVMInitializeNativeTarget(); LLVMInitializeNativeAsmPrinter(); LLVMInitializeNativeAsmParser(); if (LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) { fprintf(stderr, "failed to create execution engine\n"); abort(); } if (error) { fprintf(stderr, "error: %s\n", error); LLVMDisposeMessage(error); exit(EXIT_FAILURE); } if (argc < 3) { fprintf(stderr, "usage: %s x y\n", argv[0]); exit(EXIT_FAILURE); } long long x = strtoll(argv[1], NULL, 10); long long y = strtoll(argv[2], NULL, 10); LLVMGenericValueRef args[] {LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0), LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)}; printf("args[0]: %d\n", (int)LLVMGenericValueToInt(args[0], 0)); printf("args[1]: %d\n", (int)LLVMGenericValueToInt(args[1], 0)); LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args); printf("result: %d\n", (int)LLVMGenericValueToInt(res, 0)); LLVMDumpModule(mod); // Write out bitcode to file if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) { fprintf(stderr, "error writing bitcode to file, skipping\n"); } LLVMDisposeBuilder(builder); LLVMDisposeExecutionEngine(engine); } Here's what I see when I run it: $ ./capi_test 5 6 args[0]: 5 args[1]: 6 result: 5 ; ModuleID = 'my_module' source_filename = "my_module" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" define i32 @sum(i32, i32) { entry: %tmp = add i32 %0, %1 ret i32 %tmp } It seems to fail to add, and always returns the first argument. Any help greatly appreciated. Toshi -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170125/b2b8709f/attachment.html>
Hi, On 2017-01-25 15:17:04 -0800, Toshiyasu Morita via llvm-dev wrote:> long long x = strtoll(argv[1], NULL, 10); > long long y = strtoll(argv[2], NULL, 10); > > LLVMGenericValueRef args[] > {LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0), > > LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)}; > > printf("args[0]: %d\n", (int)LLVMGenericValueToInt(args[0], 0)); > printf("args[1]: %d\n", (int)LLVMGenericValueToInt(args[1], 0)); > > LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args); > > printf("result: %d\n", (int)LLVMGenericValueToInt(res, 0));> It seems to fail to add, and always returns the first argument. > Any help greatly appreciated.I don't think LLVMGenericValueToInt / LLVMRunFunction really work with mcjit. I'd bet you'd see better results if you'd use LLVMGetFunctionAddress, cast the returned pointer to the correc type, and then call the function via that. Greetings, Andres Freund
Thanks for the tip - getting closer: $ ./capi_test 5 6 args[0]: 5 args[1]: 6 result: 4294959200 Here's the code I changed: printf("args[0]: %d\n", (int)LLVMGenericValueToInt(args[0], 0)); printf("args[1]: %d\n", (int)LLVMGenericValueToInt(args[1], 0)); uint64_t (*func)(); func = (uint64_t (*)())LLVMGetFunctionAddress(engine, "sum"); printf("result: %lu\n", (*func)()); Anything else I should look at? Toshi On Wed, Jan 25, 2017 at 5:20 PM, Andres Freund <andres at anarazel.de> wrote:> Hi, > > On 2017-01-25 15:17:04 -0800, Toshiyasu Morita via llvm-dev wrote: > > long long x = strtoll(argv[1], NULL, 10); > > long long y = strtoll(argv[2], NULL, 10); > > > > LLVMGenericValueRef args[] > > {LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0), > > > > LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0)}; > > > > printf("args[0]: %d\n", (int)LLVMGenericValueToInt(args[0], 0)); > > printf("args[1]: %d\n", (int)LLVMGenericValueToInt(args[1], 0)); > > > > LLVMGenericValueRef res = LLVMRunFunction(engine, sum, 2, args); > > > > printf("result: %d\n", (int)LLVMGenericValueToInt(res, 0)); > > > It seems to fail to add, and always returns the first argument. > > Any help greatly appreciated. > > I don't think LLVMGenericValueToInt / LLVMRunFunction really work with > mcjit. I'd bet you'd see better results if you'd use > LLVMGetFunctionAddress, cast the returned pointer to the correc type, > and then call the function via that. > > Greetings, > > Andres Freund >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170125/f2bf1adf/attachment.html>