首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lli: LLVM错误:无法选择: X86ISD::WrapperRIP TargetGlobalTLSAddress:i64

lli: LLVM错误:无法选择: X86ISD::WrapperRIP TargetGlobalTLSAddress:i64
EN

Stack Overflow用户
提问于 2017-02-03 11:11:03
回答 2查看 762关注 0票数 9

在Linux(Debian)上使用clang++ -S -emit-llvm main.cpp && lli main.ll运行以下代码

代码语言:javascript
复制
#include <future>

int main () {
  return std::async([]{return 1;}).get();
}

由于以下错误,无法在lli上运行:

代码语言:javascript
复制
LLVM ERROR: Cannot select: 0xd012e0: 
     i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i8** @_ZSt15__once_callable> 0 [TF=10]

 0xd020c0: i64 = TargetGlobalTLSAddress<i8** @_ZSt15__once_callable> 0 [TF=10]
In function: _ZSt9call_onceIMNSt13__future_base13_State_baseV2EFvPSt8functionIFSt10unique_ptrINS0_12_Result_baseENS4_8_DeleterEEvEEPbEJPS1_S9_SA_EEvRSt9once_flagOT_DpOT0_

问题:

什么意思?

有什么编译器标志可以解决这个问题吗?

使用-stdlib=libc++可以成功编译和运行*;libstdc++使用哪些特定特性导致了这个问题?

编辑:

这个问题背后的动机是了解libc++和libstdc++之间的差异,这会导致llvm orcjit中的特定错误消息(在Linux上)。

在OSX上,gcc已被废弃,默认使用libc++。要在OSX上重现此错误,您可能需要安装gcc &使用-stdlib=libstdc++

下面是llvm-ir (不幸的是,直接将它嵌入这里太大了)

EN

回答 2

Stack Overflow用户

发布于 2017-02-05 18:14:50

编辑:

结果发现,错误是由于JITer中缺乏对TLS的支持所致。这个答案描述了另一个与链接和lli有关的问题。

如果您查看clang++ -std=c++11 -S -emit-llvm test.cpp生成的IR,您会发现许多符号(例如_ZNSt6futureIiE3getEv )只被声明,而从未定义过。链接器从未被调用,因为-S“只运行预处理和编译步骤”(clang )。

lli只执行IR模块而不进行“隐式”链接,它如何知道要链接到哪个库?

对此有不同的解决方案,具体取决于使用lli的原因:

  • 编译和链接IR模块:llc main.cpp && clang++ -lpthread main.s (What is the correct link options to use std::thread in GCC under linux?是必需的)
  • (未经确认)在运行LD_PRELOAD="x.so y.so"之前使用lli强制加载库
  • 使用LoadLibraryPermanently(nullptr) (将程序符号添加到搜索空间)和LoadLibraryPermanently(file, err)作为附加库(s. 1DynamicLibrary.html)。

我只能猜测为什么libc++在我的机器上失败了,所以它能为您工作,但大概是因为它已经加载到lli中了,并且lli调用sys::DynamicLibrary::LoadLibraryPermanently(nullptr)将程序的符号添加到它的JIT搜索空间(s. 40/tools/lli/OrcLazyJIT.cpp#L110)。

票数 2
EN

Stack Overflow用户

发布于 2017-02-07 16:43:42

LLVM邮件列表指出:

什么意思?

orcjit中的llvm后端当前不支持线程本地存储(TLS)。

最起码的例子是:

代码语言:javascript
复制
extern thread_local int tls;
int main() {
    tls = 42;
    return 0;
}

使用-stdlib=libc++可以成功编译和运行*;libstdc++使用哪些特定特性导致了这个问题?

这是因为libc++未来::get实现不使用thread_local关键字。

有什么编译器标志可以解决这个问题吗?

目前还没有解决办法。使用lli -relocation-model=pic可以通过重新定位失败来解决这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42022864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档