The following code is currently does not work in lli:
//main.cpp
extern thread_local int tls;
int main() {
tls = 42;
return 0;
}
//clang++ -S -emit-llvm main.cpp && lli main.ll
llvm-ir:
; ModuleID = 'main.cpp'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@tls = external thread_local global i32, align 4
; Function Attrs: norecurse uwtable
define i32 @main() #0 {
%1 = alloca i32, align 4
store i32 0, i32* %1, align 4
%2 = call i32* @_ZTW3tls()
store i32 42, i32* %2, align 4
ret i32 0
}
define weak_odr hidden i32* @_ZTW3tls() {
br i1 icmp ne (void ()* @_ZTH3tls, void ()* null), label %1, label %2
; <label>:1 ; preds = %0
call void @_ZTH3tls()
br label %2
; <label>:2 ; preds = %1, %0
ret i32* @tls
}
declare extern_weak void @_ZTH3tls()
It causes the following error:
LLVM ERROR: Cannot select: 0x55ec0e9c3a60: i64 = X86ISD::WrapperRIP
TargetGlobalTLSAddress:i64<i32* @tls> 0 [TF=10]
0x55ec0e9c3858: i64 = TargetGlobalTLSAddress<i32* @tls> 0 [TF=10]
In function: _ZTW3tls
Is there a way to emulate TLS and transform the llvm-ir to make this work ?
Would it be feasible to use a global map from thread_id to pointers and replace every occurrence of thread-local with allocator/deallocator/getter/setter ?
Are -femulated-tls
and -ftls-model
of any use ?
related questions:
how to perform TargetLowering in a IR-trasformation pass?
http://lists.llvm.org/pipermail/llvm-dev/2017-February/109947.html
Since you haven't said what the error is that you're seeing I'm assuming it's something of the form
LLVM ERROR: Program used external function '_ZTH3tls' which could not be resolved!
This is a linking error, which is actually referring to the fact that tls
is declared as having external linkage, but there isn't another definition to link to (at least that you've posted).
Replace
extern thread_local int tls;
with
thread_local int tls;
The compiler will then generate the following IR
@tls = thread_local global i32 0, align 4
If you actually need to have external linkage and use lli
, you'll need to link the llvm files with llvm-link
first since lli
doesn't have the ability to link for itself.
e.g.
ext.cpp
thread_local int tls = 0;
main.cpp
extern thread_local int tls;
int main() {
tls = 42;
return 0;
}
Compiling this will generate ext.ll
and main.ll
. Run llvm-link -S ext.ll main.ll > output.ll
to get the linked file and then lli output.ll
should also work.
Let me know if that settles it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With