链接时错误地折叠了LLVM IR类型(C++API)

LLVM IR types being collapsed wrongly when linking (C++ API)

本文关键字:类型 IR C++API LLVM 错误 折叠 链接      更新时间:2023-10-16

开门见山--我正试图将两个(或多个)llvm模块链接在一起,但我遇到了来自llvm的某个奇怪错误。

我不想发布太多代码,所以我将在这里使用一堆伪代码。

我有3个模块,比方说A、B和C。A是主模块;用它初始化llvm::Linker,B和C是二次模块;我叫linker.linkInModule(B and C)

所有3个模块都定义了以下两种类型:

%String = type { i8*, i64 }
%Character = type { i8*, i64 }

请注意,它们具有相同的成员类型。此外,函数foo被定义为(在模块B中):

define i1 @_ZN9Character7hasDataEv(%Character*) { }

这个函数是在模块A和C中声明的。现在,一切看起来都很好——这个函数是从模块A和模块C调用的,IR看起来很正常,就像这样:

%21 = call i1 @_ZN9Character7hasDataEv(%Character* %4)

问题来了:当所有3个模块链接在一起时,这些类型会发生一些事情:

  1. 它们失去了自己的名字,变成了%2(%String)和%3(%Character)
  2. 它们似乎合并在一起了

奇怪的是,虽然这种转换发生在模块A和C中,但错误只发生在C中——请注意,A是所谓的"主"模块。

链接文件的功能定义现在是

define i1 @_ZN9Character7hasDataEv(%2*)

注意%Character%3是如何变成%2的。此外,在调用站点,可能是试图取消合并类型,我得到的是:

%10 = call i1 bitcast (i1 (%2*)* @_ZN9Character7hasDataEv to i1 (%3*)*)(%2* %2)

奇怪的是,尽管函数是从i1 (%2*)强制转换为%3 (%2*)的,但传递的参数(arg.1)的类型仍然是%2。怎么回事?

请注意,在模块A中,发生的一切都做得很好,没有错误。这种情况发生在许多功能中,但仅发生在模块C中。

我尝试过通过将这些文件复制粘贴到.ll文件并调用llvm-linkllvm-dis来复制它,但是1。类型不合并,以及2。不存在这样的bug。

谢谢。。。?

好吧,事实证明,在llvm IRC通道中翻了一番之后,llvm::Linker应该与一个空的llvm:模块一起用作启动模块。

此外,在我的用例中,我在链接在一起的不同模块中重用相同的llvm::Type(内存中的实际内容)。他们说这并不违法,但从未进行过测试,所以\_(ツ)_/

因此,无论如何,通过从一个传递给链接器的空模块开始,问题就得到了解决。