<div dir="ltr"><div>Hi LLVM-dev,</div><div><br></div><div>I am working on a runtime system that has task migration, e.g. a task can be migrated between different threads. So a function can start executing on one thread, call a function (that might call into the function),</div><div>and then execute onto a different thread. This poses a problem with thread local variables. As an example, take the program below. After the call to `callee` we might have switched threads and thus we need to</div><div>recalculate the location of the thread local variable. <br></div><div><br></div><div>```</div><div>@var = available_externally thread_local global i32 0, align 4<br><br>declare void @callee()<br><br>define signext i32 @main() nounwind {<br>    entry:<br>    %0 = load i32, i32* @var, align 4<br>    call void @callee()<br>    %1 = load i32, i32* @var, align 4<br>    %2 = icmp eq i32 %0, %1<br>    %3 = zext i1 %2 to i32<br>    ret i32 %3<br>}</div><div>```</div><div><br></div><div>As far as I can tell there is no current mechanism to inform LLVM that thread migration might occur, and it depends on the backend what behaviour you might get.</div><div><br></div><div>As an example compiling with `x86-64-unknown-linux-gnu`, we get:</div><div><br></div><div>```</div><div> movq    var@GOTTPOFF(%rip), %rbx<br>      movl    %fs:(%rbx), %ebp<br>      callq   callee@PLT<br>    xorl    %eax, %eax<br>    cmpl    %fs:(%rbx), %ebp</div><div>```</div><div><br></div><div>Which happens to be correct. On Darwin on the other hand:</div><div><br></div><div>```</div><div>   movq    _var@TLVP(%rip), %rdi<br> callq   *(%rdi)<br>       movq    %rax, %rbx<br>    movl    (%rax), %ebp<br>  callq   _callee<br>       xorl    %eax, %eax<br>    cmpl    (%rbx), %ebp</div><div>```</div><div><br></div><div>the address for the TLS get's CSE'd, and thus the load could be incorrect.</div><div><br></div><div>Has there been any prior work on supporting thread migration + thread local storage?</div><div><br></div><div>Kind regards,</div><div>Valentin<br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div>