Hello,
[Using LLVM r155315, according to `svn log | head`]
I am experimenting with programatically building and jitting functions in a
module, and I seem to be coming across a crash in some generated code. Using the
llvm-c interface I build up the module which dumps like this:
; ModuleID = 'MyModule'
target datalayout = "i686-apple-darwin11"
target triple = "i686-apple-darwin11"
define i32 @functionName(i32 %m, i32 %x, i32 %b) {
entry:
%mx = mul i32 %m, %x
%y = add i32 %mx, %b
ret i32 %y
}
Which looks OK to me. Note I'm not 100% sure (actually, I suspect is wrong)
about the 'target datalayout' but with or without that line makes no
difference to my results.
When I attempt to run the JIT (interpreter works fine) I get a EXC_BAD_ACCESS
with the following backtrace:
* thread #1: tid = 0x2007, 0x0000000102e00042, stop reason = EXC_BAD_ACCESS
(code=1, address=0x60c93a2c)
frame #0: 0x0000000102e00042
frame #1: 0x00000001015c01fb
LLVMPlayGround`llvm::JIT::runFunction(llvm::Function*,
std::vector<llvm::GenericValue, std::allocator<llvm::GenericValue> >
const&) + 4747 at JIT.cpp:547
frame #2: 0x00000001015a0db2 LLVMPlayGround`LLVMRunFunction + 322 at
ExecutionEngineBindings.cpp:195
frame #3: 0x0000000101096125 LLVMPlayGround`main + 741 at main.c:91
frame #4: 0x0000000101095e34 LLVMPlayGround`start + 52
Which looks to be in some non-c code. At least XCode cannot find any
corresponding source:
0x102e00042: movl $10, (%rsp) <-- DIE
0x102e00049: movl $5, 4(%rsp)
0x102e00051: movl $1, 8(%rsp)
0x102e00059: movl %eax, 24(%rsp)
0x102e0005d: movl %ecx, 20(%rsp)
It looks like marshalling the 3 arguments to my function.
Looking at rsp it looks like the top 32bits have been truncated, compared to
other pointers floating around the system:
rbp = 0x00007fff60c94070
rsp = 0x0000000060c93a2c
r8 = 0x00007fff60c93800
r9 = 0x00007fff60c93808
If I use the debugger to poke 0x00007fff into the top half of rsp, stepping
through works, and after one jump I get to my function; I see the mul and add
instruction. Continuing to step, I need one more fixup of rsp (perhaps
corresponding to two jitted functions: mine, and the auto-built nullary stub?)
before returning to my main function.
Is there anything obvious I've missed? Sorry for the long mail but I figure
if I put all my data, then where I went wrong would be more obvious to someone
who knows what they're doing :)
Thanks, and please let me know if there's anything extra I can add.
-DavidM
PS: below is my complete source.
#include <stdio.h>
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include "llvm-c/Core.h"
#include "llvm-c/ExecutionEngine.h"
int main(int argc, const char * argv[])
{
LLVMContextRef llvm;
llvm = LLVMContextCreate();
LLVMModuleRef module;
module = LLVMModuleCreateWithNameInContext("MyModule", llvm);
//LLVMSetDataLayout(module, "i686-apple-darwin11"); <-- is
needed? What is correct?
LLVMSetTarget(module, "i686-apple-darwin11");
LLVMTypeRef int32 = LLVMInt32TypeInContext(llvm);
LLVMTypeRef funcType;
LLVMTypeRef threeInts[] = {int32, int32, int32};
funcType = LLVMFunctionType(int32, threeInts, 3, 0);
LLVMValueRef func;
func = LLVMAddFunction(module, "functionName", funcType);
LLVMValueRef mParam = LLVMGetParam(func, 0);
LLVMSetValueName(mParam, "m");
LLVMValueRef xParam = LLVMGetParam(func, 1);
LLVMSetValueName(xParam, "x");
LLVMValueRef bParam = LLVMGetParam(func, 2);
LLVMSetValueName(bParam, "b");
LLVMBasicBlockRef entryBB;
entryBB = LLVMAppendBasicBlockInContext(llvm, func, "entry");
LLVMBuilderRef builder;
builder = LLVMCreateBuilderInContext(llvm);
LLVMPositionBuilderAtEnd(builder, entryBB);
LLVMValueRef mx;
mx = LLVMBuildMul(builder, mParam, xParam, "mx");
LLVMValueRef y;
y = LLVMBuildAdd(builder, mx, bParam, "y");
LLVMValueRef retInst;
retInst = LLVMBuildRet(builder, y);
(void) retInst;
LLVMDisposeBuilder(builder);
LLVMLinkInJIT();
LLVMLinkInInterpreter();
LLVMInitializeNativeTarget();
LLVMDumpModule(module);
/* Now run it! */
LLVMExecutionEngineRef jit = NULL;
char *err;
// LLVMBool result = LLVMCreateExecutionEngineForModule(&jit, module,
&err);
LLVMBool result = LLVMCreateJITCompilerForModule(&jit, module, 0,
&err);
if (result) {
printf("Fail: %s\n", err);
return -1;
}
printf("JIT is %p\n", jit);
LLVMGenericValueRef argM = LLVMCreateGenericValueOfInt(int32, 10, 0);
LLVMGenericValueRef argX = LLVMCreateGenericValueOfInt(int32, 5, 0);
LLVMGenericValueRef argB = LLVMCreateGenericValueOfInt(int32, 1, 0);
LLVMGenericValueRef args[] = {argM, argX, argB};
LLVMGenericValueRef result2 = LLVMRunFunction(jit, func, 3, args);
unsigned long long answer = LLVMGenericValueToInt(result2, 0);
printf("And the answer is %d\n", (int)answer);
LLVMDisposeModule(module);
LLVMContextDispose(llvm);
return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20120425/bb08fbdf/attachment.html>
Hi David,
I'm not certain, but to me the "LLVMSetTarget(module,
"i686-apple-darwin11");" line looks suspicious. I'm not
familiar with all the ins and outs of how target triples get handled, but it
looks to me like that's requesting 32-bit code.
I think that if you omit that line completely then the target will be inferred
from the execution environment. My best guess as to what you would want if you
do want to specify something explicit is "x86_64-apple-darwin11".
Someone who knows more about how the target works may correct me.
-Andy
From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On
Behalf Of David Mirabito
Sent: Tuesday, April 24, 2012 11:49 PM
To: LLVM Developers Mailing List
Subject: [LLVMdev] Crash in JIT
Hello,
[Using LLVM r155315, according to `svn log | head`]
I am experimenting with programatically building and jitting functions in a
module, and I seem to be coming across a crash in some generated code. Using the
llvm-c interface I build up the module which dumps like this:
; ModuleID = 'MyModule'
target datalayout = "i686-apple-darwin11"
target triple = "i686-apple-darwin11"
define i32 @functionName(i32 %m, i32 %x, i32 %b) {
entry:
%mx = mul i32 %m, %x
%y = add i32 %mx, %b
ret i32 %y
}
Which looks OK to me. Note I'm not 100% sure (actually, I suspect is wrong)
about the 'target datalayout' but with or without that line makes no
difference to my results.
When I attempt to run the JIT (interpreter works fine) I get a EXC_BAD_ACCESS
with the following backtrace:
* thread #1: tid = 0x2007, 0x0000000102e00042, stop reason = EXC_BAD_ACCESS
(code=1, address=0x60c93a2c)
frame #0: 0x0000000102e00042
frame #1: 0x00000001015c01fb
LLVMPlayGround`llvm::JIT::runFunction(llvm::Function*,
std::vector<llvm::GenericValue, std::allocator<llvm::GenericValue> >
const&) + 4747 at JIT.cpp:547
frame #2: 0x00000001015a0db2 LLVMPlayGround`LLVMRunFunction + 322 at
ExecutionEngineBindings.cpp:195
frame #3: 0x0000000101096125 LLVMPlayGround`main + 741 at main.c:91
frame #4: 0x0000000101095e34 LLVMPlayGround`start + 52
Which looks to be in some non-c code. At least XCode cannot find any
corresponding source:
0x102e00042: movl $10, (%rsp) <-- DIE
0x102e00049: movl $5, 4(%rsp)
0x102e00051: movl $1, 8(%rsp)
0x102e00059: movl %eax, 24(%rsp)
0x102e0005d: movl %ecx, 20(%rsp)
It looks like marshalling the 3 arguments to my function.
Looking at rsp it looks like the top 32bits have been truncated, compared to
other pointers floating around the system:
rbp = 0x00007fff60c94070
rsp = 0x0000000060c93a2c
r8 = 0x00007fff60c93800
r9 = 0x00007fff60c93808
If I use the debugger to poke 0x00007fff into the top half of rsp, stepping
through works, and after one jump I get to my function; I see the mul and add
instruction. Continuing to step, I need one more fixup of rsp (perhaps
corresponding to two jitted functions: mine, and the auto-built nullary stub?)
before returning to my main function.
Is there anything obvious I've missed? Sorry for the long mail but I figure
if I put all my data, then where I went wrong would be more obvious to someone
who knows what they're doing :)
Thanks, and please let me know if there's anything extra I can add.
-DavidM
PS: below is my complete source.
#include <stdio.h>
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include "llvm-c/Core.h"
#include "llvm-c/ExecutionEngine.h"
int main(int argc, const char * argv[])
{
LLVMContextRef llvm;
llvm = LLVMContextCreate();
LLVMModuleRef module;
module = LLVMModuleCreateWithNameInContext("MyModule", llvm);
//LLVMSetDataLayout(module, "i686-apple-darwin11"); <-- is
needed? What is correct?
LLVMSetTarget(module, "i686-apple-darwin11");
LLVMTypeRef int32 = LLVMInt32TypeInContext(llvm);
LLVMTypeRef funcType;
LLVMTypeRef threeInts[] = {int32, int32, int32};
funcType = LLVMFunctionType(int32, threeInts, 3, 0);
LLVMValueRef func;
func = LLVMAddFunction(module, "functionName", funcType);
LLVMValueRef mParam = LLVMGetParam(func, 0);
LLVMSetValueName(mParam, "m");
LLVMValueRef xParam = LLVMGetParam(func, 1);
LLVMSetValueName(xParam, "x");
LLVMValueRef bParam = LLVMGetParam(func, 2);
LLVMSetValueName(bParam, "b");
LLVMBasicBlockRef entryBB;
entryBB = LLVMAppendBasicBlockInContext(llvm, func, "entry");
LLVMBuilderRef builder;
builder = LLVMCreateBuilderInContext(llvm);
LLVMPositionBuilderAtEnd(builder, entryBB);
LLVMValueRef mx;
mx = LLVMBuildMul(builder, mParam, xParam, "mx");
LLVMValueRef y;
y = LLVMBuildAdd(builder, mx, bParam, "y");
LLVMValueRef retInst;
retInst = LLVMBuildRet(builder, y);
(void) retInst;
LLVMDisposeBuilder(builder);
LLVMLinkInJIT();
LLVMLinkInInterpreter();
LLVMInitializeNativeTarget();
LLVMDumpModule(module);
/* Now run it! */
LLVMExecutionEngineRef jit = NULL;
char *err;
// LLVMBool result = LLVMCreateExecutionEngineForModule(&jit, module,
&err);
LLVMBool result = LLVMCreateJITCompilerForModule(&jit, module, 0,
&err);
if (result) {
printf("Fail: %s\n", err);
return -1;
}
printf("JIT is %p\n", jit);
LLVMGenericValueRef argM = LLVMCreateGenericValueOfInt(int32, 10, 0);
LLVMGenericValueRef argX = LLVMCreateGenericValueOfInt(int32, 5, 0);
LLVMGenericValueRef argB = LLVMCreateGenericValueOfInt(int32, 1, 0);
LLVMGenericValueRef args[] = {argM, argX, argB};
LLVMGenericValueRef result2 = LLVMRunFunction(jit, func, 3, args);
unsigned long long answer = LLVMGenericValueToInt(result2, 0);
printf("And the answer is %d\n", (int)answer);
LLVMDisposeModule(module);
LLVMContextDispose(llvm);
return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20120425/d2bd6a0b/attachment.html>
Hi Andy,
You are of course correct. My mail bounced because I forgot I wasn't
actually subscribed (fixed that too!) and in the meantime I nutted it out on
IRC.
So it turns out with that triple, it was generating a 32-bit stack manipulation
('subl #12' - which had scrolled away in XCode when I pasted into my
original email), which cleared the top bits and caused trouble. Changing the
triple to exactly as you mentioned means things start to work perfectly.
My x86/x64 is pretty terrible so it took me longer to figure exactly what was
happening than maybe it should have :)
Although I am somewhat (but not overly) surprised the execution engine accepted
the module with such a target, and didn't complain that it didn't match
'InitializeNativeTarget()'. But for now I'm just glad it works.
I've since managed to get the JIT'd code to import and call helper
functions my app provides - it's really *cool* stuff and am excited to
further the project!
Cheers for the tips,
DavidM
On 25/04/2012, at 6:36 PM, Kaylor, Andrew wrote:
> Hi David,
>
> I’m not certain, but to me the “LLVMSetTarget(module,
"i686-apple-darwin11");” line looks suspicious. I’m not familiar with
all the ins and outs of how target triples get handled, but it looks to me like
that’s requesting 32-bit code.
>
> I think that if you omit that line completely then the target will be
inferred from the execution environment. My best guess as to what you would
want if you do want to specify something explicit is “x86_64-apple-darwin11”.
>
> Someone who knows more about how the target works may correct me.
>
> -Andy
>
> From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at
cs.uiuc.edu] On Behalf Of David Mirabito
> Sent: Tuesday, April 24, 2012 11:49 PM
> To: LLVM Developers Mailing List
> Subject: [LLVMdev] Crash in JIT
>
> Hello,
>
> [Using LLVM r155315, according to `svn log | head`]
>
> I am experimenting with programatically building and jitting functions in a
module, and I seem to be coming across a crash in some generated code. Using the
llvm-c interface I build up the module which dumps like this:
> ; ModuleID = 'MyModule'
> target datalayout = "i686-apple-darwin11"
> target triple = "i686-apple-darwin11"
>
> define i32 @functionName(i32 %m, i32 %x, i32 %b) {
> entry:
> %mx = mul i32 %m, %x
> %y = add i32 %mx, %b
> ret i32 %y
> }
>
> Which looks OK to me. Note I'm not 100% sure (actually, I suspect is
wrong) about the 'target datalayout' but with or without that line makes
no difference to my results.
>
> When I attempt to run the JIT (interpreter works fine) I get a
EXC_BAD_ACCESS with the following backtrace:
> * thread #1: tid = 0x2007, 0x0000000102e00042, stop reason = EXC_BAD_ACCESS
(code=1, address=0x60c93a2c)
> frame #0: 0x0000000102e00042
> frame #1: 0x00000001015c01fb
LLVMPlayGround`llvm::JIT::runFunction(llvm::Function*,
std::vector<llvm::GenericValue, std::allocator<llvm::GenericValue> >
const&) + 4747 at JIT.cpp:547
> frame #2: 0x00000001015a0db2 LLVMPlayGround`LLVMRunFunction + 322 at
ExecutionEngineBindings.cpp:195
> frame #3: 0x0000000101096125 LLVMPlayGround`main + 741 at main.c:91
> frame #4: 0x0000000101095e34 LLVMPlayGround`start + 52
>
> Which looks to be in some non-c code. At least XCode cannot find any
corresponding source:
> 0x102e00042: movl $10, (%rsp) <-- DIE
> 0x102e00049: movl $5, 4(%rsp)
> 0x102e00051: movl $1, 8(%rsp)
> 0x102e00059: movl %eax, 24(%rsp)
> 0x102e0005d: movl %ecx, 20(%rsp)
> It looks like marshalling the 3 arguments to my function.
>
> Looking at rsp it looks like the top 32bits have been truncated, compared
to other pointers floating around the system:
> rbp = 0x00007fff60c94070
> rsp = 0x0000000060c93a2c
> r8 = 0x00007fff60c93800
> r9 = 0x00007fff60c93808
>
> If I use the debugger to poke 0x00007fff into the top half of rsp, stepping
through works, and after one jump I get to my function; I see the mul and add
instruction. Continuing to step, I need one more fixup of rsp (perhaps
corresponding to two jitted functions: mine, and the auto-built nullary stub?)
before returning to my main function.
>
> Is there anything obvious I've missed? Sorry for the long mail but I
figure if I put all my data, then where I went wrong would be more obvious to
someone who knows what they're doing :)
>
> Thanks, and please let me know if there's anything extra I can add.
> -DavidM
>
> PS: below is my complete source.
>
>
> #include <stdio.h>
> #define __STDC_LIMIT_MACROS
> #define __STDC_CONSTANT_MACROS
>
> #include "llvm-c/Core.h"
> #include "llvm-c/ExecutionEngine.h"
>
> int main(int argc, const char * argv[])
> {
>
> LLVMContextRef llvm;
> llvm = LLVMContextCreate();
>
> LLVMModuleRef module;
> module = LLVMModuleCreateWithNameInContext("MyModule", llvm);
> //LLVMSetDataLayout(module, "i686-apple-darwin11"); <-- is
needed? What is correct?
> LLVMSetTarget(module, "i686-apple-darwin11");
>
>
> LLVMTypeRef int32 = LLVMInt32TypeInContext(llvm);
>
> LLVMTypeRef funcType;
> LLVMTypeRef threeInts[] = {int32, int32, int32};
> funcType = LLVMFunctionType(int32, threeInts, 3, 0);
>
> LLVMValueRef func;
> func = LLVMAddFunction(module, "functionName", funcType);
>
> LLVMValueRef mParam = LLVMGetParam(func, 0);
> LLVMSetValueName(mParam, "m");
>
> LLVMValueRef xParam = LLVMGetParam(func, 1);
> LLVMSetValueName(xParam, "x");
>
> LLVMValueRef bParam = LLVMGetParam(func, 2);
> LLVMSetValueName(bParam, "b");
>
> LLVMBasicBlockRef entryBB;
> entryBB = LLVMAppendBasicBlockInContext(llvm, func, "entry");
>
> LLVMBuilderRef builder;
> builder = LLVMCreateBuilderInContext(llvm);
>
> LLVMPositionBuilderAtEnd(builder, entryBB);
>
> LLVMValueRef mx;
> mx = LLVMBuildMul(builder, mParam, xParam, "mx");
>
> LLVMValueRef y;
> y = LLVMBuildAdd(builder, mx, bParam, "y");
>
> LLVMValueRef retInst;
> retInst = LLVMBuildRet(builder, y);
> (void) retInst;
>
>
> LLVMDisposeBuilder(builder);
>
>
> LLVMLinkInJIT();
> LLVMLinkInInterpreter();
> LLVMInitializeNativeTarget();
>
> LLVMDumpModule(module);
>
> /* Now run it! */
>
> LLVMExecutionEngineRef jit = NULL;
> char *err;
> // LLVMBool result = LLVMCreateExecutionEngineForModule(&jit,
module, &err);
> LLVMBool result = LLVMCreateJITCompilerForModule(&jit, module, 0,
&err);
> if (result) {
> printf("Fail: %s\n", err);
> return -1;
> }
> printf("JIT is %p\n", jit);
>
> LLVMGenericValueRef argM = LLVMCreateGenericValueOfInt(int32, 10, 0);
> LLVMGenericValueRef argX = LLVMCreateGenericValueOfInt(int32, 5, 0);
> LLVMGenericValueRef argB = LLVMCreateGenericValueOfInt(int32, 1, 0);
>
> LLVMGenericValueRef args[] = {argM, argX, argB};
> LLVMGenericValueRef result2 = LLVMRunFunction(jit, func, 3, args);
> unsigned long long answer = LLVMGenericValueToInt(result2, 0);
> printf("And the answer is %d\n", (int)answer);
>
> LLVMDisposeModule(module);
> LLVMContextDispose(llvm);
> return 0;
> }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20120425/d0ef1754/attachment.html>