带有Itanium的LLVM IR意外终止程序

时间:2014-09-14 23:06:23

标签: llvm

我有一个源程序,我的前端已翻译成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错误。

1 个答案:

答案 0 :(得分:1)

这是MCJIT中的一个错误 - 如果你只调用一次MCJIT,程序执行得很好。