Hello,<br><br>I apologize if this has already been fixed or reported.  I believe there is a bug in the way the optimizer deals with thread_local variables.  The attached program, test.c, has a thread-local variable "int Foo" and a global variable "int *Ptr".  The program takes the following steps:<br>
<br>1) The main thread spawns a new thread and waits<br>2) The new thread writes Foo = 50 and Ptr = &Foo, then signals the main thread and waits<br>3) The main thread prints *Ptr, releases the new thread, and exits<br>
<br>The crux of this example is that the main thread obtains a pointer to the new thread's TLS via "Ptr".  When I compile with gcc, the program prints "50" as expected.  When I compile with LLVM, the program prints "0".  This is confirmed in the following three versions of LLVM:<br>
* the 2.9 release<br>* whatever version of LLVM is driving <a href="http://llvm.org/demo/index.cgi">http://llvm.org/demo/index.cgi</a><br>* svn revision 167568 on trunk (this was the most-recent revision as of a few hours ago)<br>
<br>I've attached the optimized bytecode in test.ll.  This was produced by <a href="http://llvm.org/demo/index.cgi">http://llvm.org/demo/index.cgi</a> with "LTO" checked.  You can see the bug in main(), where LLVM has optimized the load "*Ptr" into the following instructions:<br>
<br>  %.b = load i1* @Foo.b, align 1   ; main() loads its own @Foo.b, not the @Foo.b written by run()<br>  %5 = select i1 %.b, i32 50, i32 0<br><br>My guess is that the optimizer does not realize that thread_local addresses are not constant in the same way that global addresses are constant, since each thread_local variable actually names N variables, one for each of N running threads.  Thus, it's not safe to optimize across two accesses of a thread_local variable unless it can be proven that both accesses will be performed by the same thread.<br>
<br>In terms of LLVM's design, I've noticed that thread_local variables are represented in the same way as ordinary variables (via llvm::GlobalVariable) except that the "isThreadLocal" flag is true.  This strikes me as a potential for confusion, because you have this one corner case -- thread_locals -- in which an "llvm::Constant" is not really a "constant" in the same way as other constants.  This might be related to <a href="http://llvm.org/bugs/show_bug.cgi?id=13720">http://llvm.org/bugs/show_bug.cgi?id=13720</a>, and perhaps a few other bugs.<br>
<br>-Tom<br><br>p.s. If anyone is hit by this bug, my current workaround is to declare Ptr volatile:<br>    int * volatile Ptr;<br><br>Note that if the volatile is moved under the pointer, as in the following:<br>    volatile int * Ptr;<br>
<br>then the bug reappears, as the load "*Ptr" in main() will be incorrectly optimized to:<br>    %5 = load volatile i32* @Foo, align 4<br>