LLVM Code generation causing seg fault?
I am interested in language creation and compiler construction, and have been working through the example here: http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/. The author was using LLVM 2.6, and after making a couple changes for LLVM 2.7, I got all the code generation code to compile. When feeding the complier the test code,
int do_math( int a ) {
int x = a * 5 + 3
}
do_math( 10 )
the program works correctly until it tries to run the code, at which point it segfaults. I am in the process of building LLDB on my system, but it the meantime, anyone see an obvious se开发者_如何学Cg fault in this LLVM asm?
; ModuleID = 'main'
define internal void @main() {
entry:
%0 = call i64 @do_math(i64 10) ; <i64> [#uses=0]
ret void
}
define internal i64 @do_math(i64) {
entry:
%a = alloca i64 ; <i64*> [#uses=1]
%x = alloca i64 ; <i64*> [#uses=1]
%1 = add i64 5, 3 ; <i64> [#uses=1]
%2 = load i64* %a ; <i64> [#uses=1]
%3 = mul i64 %2, %1 ; <i64> [#uses=1]
store i64 %3, i64* %x
ret void
}
The output is just:
Segmentation fault
My arch is OS X x86_64.
Thanks.
I got same problem. I stripped down Loren's compiler and everything was working fine except execution.
Segmentation fault was caused by the fact that:
ExecutionEngine *ee = EngineBuilder(module).create();
returns NULL. To see the actual error, you need to get error string:
std::string error; ExecutionEngine *ee = EngineBuilder(module).setErrorStr(&error).create();
In your case you should probably see:
"Unable to find target for this triple (no targets are registered)
To fix that you need to call
InitializeNativeTarget();
But if you get:
JIT has not been linked in.
You should include:
llvm/ExecutionEngine/MCJIT.h
which will link JIT engine.
The LLVM ASM you posted isn't a correct translation of the C code you presented. You're allocating %a
as a stack variable, and then loading uninitialized data from it and using it. What you want to be doing is naming your argument %a
and using that value. Try using this code instead:
define internal i64 @do_math(i64 %a) {
entry:
%x = alloca i64 ; <i64*> [#uses=1]
%1 = add i64 5, 3 ; <i64> [#uses=1]
%2 = mul i64 %a, %1 ; <i64> [#uses=1]
store i64 %2, i64* %x
ret void
}
Also, your main()
prototype might not match what your C runtime library expects. And, beyond that, you do realize that you're not returning the result from do_math()
, right?
精彩评论