<div class="gmail_quote">On Fri, Nov 9, 2012 at 11:23 AM, Hans Wennborg <span dir="ltr"><<a href="mailto:hans@chromium.org" target="_blank">hans@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Tom,<br>
<div class="im"><br>
On Wed, Nov 7, 2012 at 11:43 PM, Tom Bergan <<a href="mailto:tbergan@cs.washington.edu">tbergan@cs.washington.edu</a>> wrote:<br>
> Hello,<br>
><br>
> I apologize if this has already been fixed or reported.  I believe there is<br>
> a bug in the way the optimizer deals with thread_local variables.  The<br>
> attached program, test.c, has a thread-local variable "int Foo" and a global<br>
> 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<br>
> 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<br>
> new thread's TLS via "Ptr".  When I compile with gcc, the program prints<br>
> "50" as expected.  When I compile with LLVM, the program prints "0".  This<br>
> 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" target="_blank">http://llvm.org/demo/index.cgi</a><br>
> * svn revision 167568 on trunk (this was the most-recent revision as of a<br>
> few hours ago)<br>
<br>
</div>I tried your test.c, compiled with "clang -O3", but couldn't reproduce<br>
the error you're seeing. (I was using revison 167547).<br>
<br>
What flags did you use when you compiled locally?<br>
<br>
Thanks,<br>
Hans<br>
</blockquote></div><br>Sorry for the incomplete report.  Originally, I actually compiled test.c using LTO, via "opt -std-compile-opts -std-link-opts".  The bug manifests more simply if the variables "Ptr" and "Foo" are declared static -- in this case, the bug is demonstrated directly with "clang -O3".<br>
<br>Attached are three files:<br>* test.c, which is the same as the old test.c, but with "Ptr" and "Foo" declared static<br>* test.0.ll, which was built with "clang -emit-llvm -S -O0 test.c -o test.0.ll"<br>
* test.3.ll, which was built with "clang -emit-llvm -S -O3 test.c -o test.3.ll"<br><br>To demonstrate the bug (verified with revision 167568):<br>$ clang -O3 -lpthread test.c -o test<br>$ ./test   # prints "Foo: 0"<br>
<br>It is also pretty clear that "test.3.ll" is an incorrect optimization of "test.0.ll"<br><br>Thanks for looking at this!<br>-Tom<br>