26

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

Gaetano
  • 1,090
  • 1
  • 9
  • 25
  • From what i understand of the `-femulated-tls` flag that basically does do what you are talking about, emulating tls using the same model GCC does to avoid explicit linker and system support. – Vality Feb 15 '17 at 17:35
  • 1
    unfortunately, it is not affecting the IR. -femulated-tls affects the targetlowering in the codegeneration stage when generating the binary. I need a targetlowering transformation applied to my IR, not my machine code. – Gaetano Feb 15 '17 at 20:05
  • @Gaetano - Any resolution? If so, can you post as an answer to your own question? – Frank C. Sep 07 '17 at 18:43
  • 1
    @ago unfortunately not, looks like LLVM only implements TLS-emulation in the TargetLowering pass. This pass is creating assembly from IR and seem not to be available as an IR transformation. Related question: https://stackoverflow.com/questions/42163796/how-to-perform-targetlowering-in-a-ir-trasformation-pass?rq=1 – Gaetano Sep 08 '17 at 11:29
  • @Gaetano – Have you tried to explictly specify in the IR any of the supported TLS models (e.g. `thread_local(localexec)`)? – Filippo Costa Apr 09 '18 at 12:48
  • @cornstalks added error message. – Gaetano Apr 22 '18 at 17:16
  • Hmm, I can't seem to reproduce the error. What version of LLVM is this? – Evan Jun 06 '18 at 03:51
  • I've tested it with various versions including 6.0.0 running on a X86_64 Debian – Gaetano Jun 12 '18 at 21:02
  • Yeah, I can't seem to reproduce this error. Sorry. – Evan Jun 27 '18 at 01:39

1 Answers1

1

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.

Evan
  • 508
  • 1
  • 5
  • 18