我有一个源程序,我的前端已翻译成LLVM IR。然而,IR意外地最终调用std::terminate
作为我使用的Itanium ABI EH机制的一部分。我已经盯着IR一段时间没有任何关于为什么会发生这种情况的消息。
这是我原来的IR,仅由MCJIT自己的通行证简化:
; ModuleID = 'Wide'
target datalayout = "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-itanium-elf"
%struct.__08F8D200 = type { i8 }
%struct.__08FBDC68 = type { [1 x i8] }
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS10__08FBDC68 = internal constant [13 x i8] c"10__08FBDC68\00"
@_ZTI10__08FBDC68 = internal constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([13 x i8]* @_ZTS10__08FBDC68, i32 0, i32 0) }
define i8 @"16ef5f49-dbe3-4014-a9c8-a2dbb0c1d337"() {
out_of_bounds:
%0 = alloca [1 x i8], align 1
%1 = alloca %struct.__08F8D200, align 1
%2 = alloca %struct.__08FBDC68, align 1
%3 = bitcast %struct.__08F8D200* %1 to i8*
%4 = bitcast [1 x i8]* %0 to i8*
store i8 1, i8* %3
%5 = load %struct.__08F8D200* %1
%6 = extractvalue %struct.__08F8D200 %5, 0
store i8 %6, i8* %4
%7 = call i8* @__cxa_allocate_exception(i32 1)
%8 = bitcast i8* %7 to %struct.__08FBDC68*
store %struct.__08FBDC68 undef, %struct.__08FBDC68* %2
invoke void @"5ea3408f-3d4e-4ef7-96b7-9c3dd87ae960"(%struct.__08FBDC68* %8, %struct.__08FBDC68* %2)
to label %continue unwind label %landingpad
catch_block: ; preds = %catch_continue
%9 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
catch i8* null
call void @__cxa_end_catch()
%10 = extractvalue { i8*, i32 } %9, 1
%11 = extractvalue { i8*, i32 } %9, 0
ret i8 0
catch_block1: ; preds = %landingpad3, %landingpad
%12 = phi { i8*, i32 } [ %19, %landingpad ], [ %20, %landingpad3 ]
%13 = extractvalue { i8*, i32 } %12, 1
%14 = extractvalue { i8*, i32 } %12, 0
%15 = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI10__08FBDC68 to i8*))
%16 = icmp eq i32 %13, %15
br i1 %16, label %catch_target, label %catch_continue
continue: ; preds = %out_of_bounds
%17 = bitcast i8* %7 to %struct.__08FBDC68*
%18 = bitcast %struct.__08FBDC68* %17 to i8*
invoke void @__cxa_throw(i8* %18, i8* bitcast ({ i8*, i8* }* @_ZTI10__08FBDC68 to i8*), i8* null)
to label %unreachable unwind label %landingpad3
landingpad: ; preds = %out_of_bounds
%19 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
catch i8* bitcast ({ i8*, i8* }* @_ZTI10__08FBDC68 to i8*)
catch i8* null
call void @__cxa_free_exception(i8* %7)
br label %catch_block1
landingpad3: ; preds = %continue
%20 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
catch i8* bitcast ({ i8*, i8* }* @_ZTI10__08FBDC68 to i8*)
catch i8* null
br label %catch_block1
unreachable: ; preds = %continue
unreachable
catch_target: ; preds = %catch_block1
%21 = call i8* (i8*, ...)* @__cxa_begin_catch(i8* %14)
call void @__cxa_end_catch()
ret i8 1
catch_continue: ; preds = %catch_block1
%22 = call i8* (i8*, ...)* @__cxa_begin_catch(i8* %14)
invoke void @__cxa_rethrow()
to label %unreachable5 unwind label %catch_block
unreachable5: ; preds = %catch_continue
unreachable
}
declare i8* @__cxa_allocate_exception(i32)
define void @"5ea3408f-3d4e-4ef7-96b7-9c3dd87ae960"(%struct.__08FBDC68*, %struct.__08FBDC68*) {
entry:
ret void
}
declare i32 @__gxx_personality_v0(...)
declare void @__cxa_free_exception(i8*)
declare void @__cxa_throw(i8*, i8*, i8*)
; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) #0
declare i8* @__cxa_begin_catch(i8*, ...)
declare void @__cxa_end_catch()
declare void @__cxa_rethrow()
attributes #0 = { nounwind readnone }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5.0 (tags/RELEASE_350/final)"}
有相当多的死代码,但到目前为止,我还没有完成构建我需要的工具,将缩小版本转换为我可以执行的内容并检查结果。
唯一的输出libstdc ++的EH例程给出的是" std :: terminate在抛出__08FBDC68"的实例后被调用。当然,我扔了一个,但是那里有一个着陆垫可以抓住它。我不明白为什么实施没有找到着陆垫。
为什么我的着陆垫没有降落?如果我将此IR转换为Linux上的可执行文件并执行输出,那么所有似乎都可以正常工作。当我在Windows上对它进行MCJIT时,史诗会失败。
编辑:我已经稍微改变了我的测试用例,现在它通过了。
; ModuleID = 'Wide'
target datalayout = "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-windows-itanium-elf"
%struct.__08E11DF0 = type { [1 x i8] }
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS10__08E11DF0 = internal constant [13 x i8] c"10__08E11DF0\00"
@_ZTI10__08E11DF0 = internal constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([13 x i8]* @_ZTS10__08E11DF0, i32 0, i32 0) }
define i8 @a3b850db-5539-466c-bc66-173731166e7d() {
entry:
%0 = alloca %struct.__08E11DF0, align 1
%1 = call i8* @__cxa_allocate_exception(i32 1)
%2 = bitcast i8* %1 to %struct.__08E11DF0*
store %struct.__08E11DF0 undef, %struct.__08E11DF0* %0
invoke void @"799641a0-f6b5-4af2-ad73-e9bede067f08"(%struct.__08E11DF0* %2, %struct.__08E11DF0* %0)
to label %continue unwind label %landingpad
catch_block: ; preds = %catch_continue
%3 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
catch i8* null
call void @__cxa_end_catch()
%4 = extractvalue { i8*, i32 } %3, 1
%5 = extractvalue { i8*, i32 } %3, 0
ret i8 0
catch_block1: ; preds = %landingpad3, %landingpad
%6 = phi { i8*, i32 } [ %13, %landingpad ], [ %14, %landingpad3 ]
%7 = extractvalue { i8*, i32 } %6, 1
%8 = extractvalue { i8*, i32 } %6, 0
%9 = call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI10__08E11DF0 to i8*))
%10 = icmp eq i32 %7, %9
br i1 %10, label %catch_target, label %catch_continue
continue: ; preds = %entry
%11 = bitcast i8* %1 to %struct.__08E11DF0*
%12 = bitcast %struct.__08E11DF0* %11 to i8*
invoke void @__cxa_throw(i8* %12, i8* bitcast ({ i8*, i8* }* @_ZTI10__08E11DF0 to i8*), i8* null)
to label %unreachable unwind label %landingpad3
landingpad: ; preds = %entry
%13 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
catch i8* bitcast ({ i8*, i8* }* @_ZTI10__08E11DF0 to i8*)
catch i8* null
call void @__cxa_free_exception(i8* %1)
br label %catch_block1
landingpad3: ; preds = %continue
%14 = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
catch i8* bitcast ({ i8*, i8* }* @_ZTI10__08E11DF0 to i8*)
catch i8* null
br label %catch_block1
unreachable: ; preds = %continue
unreachable
catch_target: ; preds = %catch_block1
%15 = call i8* (i8*, ...)* @__cxa_begin_catch(i8* %8)
call void @__cxa_end_catch()
ret i8 1
catch_continue: ; preds = %catch_block1
%16 = call i8* (i8*, ...)* @__cxa_begin_catch(i8* %8)
invoke void @__cxa_rethrow()
to label %unreachable5 unwind label %catch_block
unreachable5: ; preds = %catch_continue
unreachable
}
declare i8* @__cxa_allocate_exception(i32)
define void @"799641a0-f6b5-4af2-ad73-e9bede067f08"(%struct.__08E11DF0*, %struct.__08E11DF0*) {
entry:
ret void
}
declare i32 @__gxx_personality_v0(...)
declare void @__cxa_free_exception(i8*)
declare void @__cxa_throw(i8*, i8*, i8*)
; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) #0
declare i8* @__cxa_begin_catch(i8*, ...)
declare void @__cxa_end_catch()
declare void @__cxa_rethrow()
attributes #0 = { nounwind readnone }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5.0 (tags/RELEASE_350/final)"}
正如您所看到的,它基本相同,只有值数字和输入块中的一些死代码不同。我开始认为这可能是一个LLVM错误。
答案 0 :(得分:1)
这是MCJIT中的一个错误 - 如果你只调用一次MCJIT,程序执行得很好。