开发者

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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜