#include <future> int main () { return std::async([]{return 1;}).get(); }
由于以下错误,无法在lli上运行:
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使用哪些特殊功能导致此问题?
编辑:
后面这个问题的动机是要了解导致此特定错误信息(在Linux上)在LLVM的orcjit的libc和libstdc之间的差异.
在OSX上gcc已被弃用,clang默认使用libc.
要在OSX上重现此错误,您可能必须安装gcc&使用-stdlib = libstdc.
这是llvm-ir(不幸的是,大到这里直接嵌入)
解决方法
该错误原因是由于JITER中缺少TLS支持.这个答案描述了与链接和lli有关的另一个问题.
如果您从clang -std = c 11 -S -emit-llvm test.cpp中查看生成的IR,您将发现许多符号,例如_ZNSt6futureIiE3getEv,仅被声明,但从未定义.链接器从不被调用,因为-S“只运行预处理和编译步骤”(clang –help).
lli只执行IR模块并且没有“隐式”链接,应该如何知道要链接哪些库?
有不同的解决方案,这取决于你为什么使用lli:
>编译并链接IR模块:llc main.cpp&& clang -lpthread main.s(pthread is required s.What is the correct link options to use std::thread in GCC under linux?)
>(未确认)使用LD_PRELOAD =“x.so y.so”在运行lli之前强制加载库
>以编程方式JIT模块,并使用LoadLibraryPermanently(nullptr)(将程序的符号添加到搜索空间)和LoadLibraryPermanently(file,err)用于其他库(s.http://llvm.org/docs/doxygen/html/classllvm_1_1sys_1_1DynamicLibrary.html)
我只能猜测为什么libc适用于您,因为它在我的机器上失败,但可能是因为它被加载到lli已经和lli调用sys :: DynamicLibrary :: LoadLibraryPermanently(nullptr)来添加程序的符号到它的JIT搜索空间(s.https://github.com/llvm-mirror/llvm/blob/release_40/tools/lli/OrcLazyJIT.cpp#L110).