为什么这个由我的编译器生成的llvm IR是segfaulting

我正在为大学项目构建一个编译器而我正在使用llvm。

我为最小程序生成了这个IR:

; ModuleID = 'Main'
source_filename = "Main.java"

%A = type { i16 }
%Main = type { i16 }

@progvtable = constant [1 x <{ i16, i8*, i8* }>] [<{ i16, i8*, i8* }> <{ i16 0, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @1, i64 0, i64 0), i8* bitcast (i64 (%A*)* @getX to i8*) }>], align 8
@0 = constant [8 x i8] c"%lld %c0", align 8
@1 = constant [5 x i8] c"getX0", align 8

declare i32 @strcmp(i8*, i8*)

define i8* @vlookup(i16 %type, i8* %funcname) {
vlookup:
  %i = alloca i64, align 8
  %finalres = alloca i8*, align 8
  store i64 0, i64* %i, align 8
  store i8* null, i8** %finalres, align 8
  br i1 true, label %loop, label %endloop

loop:                                             ; preds = %loop, %vlookup
  %0 = load i64, i64* %i, align 8
  %1 = getelementptr inbounds [1 x <{ i16, i8*, i8* }>], [1 x <{ i16, i8*, i8* }>]* @progvtable, i64 0, i64 %0
  %2 = getelementptr <{ i16, i8*, i8* }>, <{ i16, i8*, i8* }>* %1, i32 0, i32 0
  %3 = load i16, i16* %2, align 8
  %4 = getelementptr <{ i16, i8*, i8* }>, <{ i16, i8*, i8* }>* %1, i32 0, i32 1
  %5 = load i8*, i8** %4, align 8
  %6 = getelementptr <{ i16, i8*, i8* }>, <{ i16, i8*, i8* }>* %1, i32 0, i32 2
  %7 = load i8*, i8** %6, align 8
  store i8* %7, i8** %finalres, align 8
  %8 = icmp eq i16 %3, %type
  %9 = call i32 @strcmp(i8* %5, i8* %funcname)
  %10 = icmp eq i32 %9, 0
  %11 = and i1 %10, %8
  %12 = add i64 %0, 1
  store i64 %12, i64* %i, align 8
  br i1 %11, label %loop, label %endloop

endloop:                                          ; preds = %loop, %vlookup
  %13 = load i8*, i8** %finalres, align 8
  ret i8* %13
}

declare i32 @printf(i8*, ...)

declare i8* @GC_malloc(i64)

define %A* @A_init() {
A_init:
  %0 = call i8* @GC_malloc(i64 2)
  %this = bitcast i8* %0 to %A*
  %1 = getelementptr inbounds %A, %A* %this, i32 0, i32 0
  store i16 0, i16* %1, align 8
  ret %A* %this
}

define i64 @getX(%A* %this) {
getX:
  ret i64 1
}

define %Main* @Main_init() {
Main_init:
  %0 = call i8* @GC_malloc(i64 2)
  %this = bitcast i8* %0 to %Main*
  %1 = getelementptr inbounds %Main, %Main* %this, i32 0, i32 0
  store i16 5, i16* %1, align 8
  ret %Main* %this
}

define void @main(i8**) {
main:
  %1 = alloca i8**, align 8
  store i8** %0, i8*** %1, align 8
  %args = load i8**, i8*** %1, align 8
  %2 = alloca %A*, align 8
  %3 = call %A* @A_init()
  store %A* %3, %A** %2, align 8
  %e = load %A*, %A** %2, align 8
  %4 = getelementptr inbounds %A, %A* %e, i32 0, i32 0
  %5 = load i16, i16* %4, align 8
  %6 = call i8* @vlookup(i16 %5, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @1, i64 0, i64 0))
  %7 = bitcast i8* %6 to i64 (%A*)*
  %8 = call i64 %7(%A* %e)
  %9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @0, i64 0, i64 0), i64 %8, i8 10)
  ret void
}

目前,这是未经优化的输出,但是这不是问题,我llc上面,然后我用gcc链接libgc.so然后我运行应用程序,它出现segfaults。

使用gdb我验证了segfaults发生在对strcmp的调用上,lldb显示其中一个参数为null。

我仔细研究了IR,我没有看到任何问题,但它存在段错误,为什么会发生这种情况?

对于记录@progvtable是我用virtual tables来表示支持我要实现的语言中的多态性。

我使用llvm 4和gcc 7.1.1,我的操作系统是Arch Linux x64。


愚蠢的我,这个问题非常微不足道它在这里:

br i1 %11, label %loop, label %endloop

这个指令的问题是条件操作数是打破循环而不是继续它,所有需要的是切换label %looplabel %endloop位置。

链接地址: http://www.djcxy.com/p/68701.html

上一篇: why is this llvm IR generated by my compiler is segfaulting

下一篇: Loading and storing variables using an LLVM pass