This appears to be a bug in the libstdc++ implementation of std::call_once, but it may be somewhat specific to ABI issues as there are differences between stage1 and stage2 in LE. Here are the build bot builds that started failing when I landed r271800 that switch LLVM to use std::call_once on various implementations: http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage/builds/1169 http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/2703 These fail in unit tests that use INITIALIZE_PASS which defines a function that uses std::call_once. The failure happens when the implementation of std::call_once throws std::system_error with the '-1' return of a call to pthread_once. I don't know why pthread_once would fail here. I've tried to reproduce any failure to properly initialize the std::once_flag (which contains as a member the pthread_once_t variable passed to pthread_once) but to no avail on my system. Hopefully someone who works on PPC can figure this out. Also, when I tried to disable this in r271821, it worked for ppc64le, and for stage2 in ppc64be, but not for stage1 for some reason! Really weird: http://lab.llvm.org:8011/builders/clang-ppc64be-linux-multistage/builds/2707 Again, I can't figure out how or why this would happen. Hopefully some PPC folks can figure this out.
I tried the macros on ppc64be: seurer@hogun:~/test/macro$ cat t.C #if defined(LLVM_ON_UNIX) && \ !(defined(__NetBSD__) && !defined(_LIBCPP_VERSION)) && !defined(__ppc__) #define LLVM_THREADING_USE_STD_CALL_ONCE 1 #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 1 #else #define LLVM_THREADING_USE_STD_CALL_ONCE 0 #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 #endif seurer@hogun:~/test/macro$ ~buildbots/ppc64be-clang-test/clang-ppc64be/stage1/bin/clang++ -c t.C t.C:7:2: error: LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 ^ 1 error generated. seurer@hogun:~/test/macro$ ~/gcc/install/gcc-5.3.0/bin/g++ -c t.C t.C:7:2: error: #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 ^
(In reply to comment #1) > I tried the macros on ppc64be: > > seurer@hogun:~/test/macro$ cat t.C > #if defined(LLVM_ON_UNIX) && > \ > !(defined(__NetBSD__) && !defined(_LIBCPP_VERSION)) && !defined(__ppc__) > #define LLVM_THREADING_USE_STD_CALL_ONCE 1 > #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 1 > #else > #define LLVM_THREADING_USE_STD_CALL_ONCE 0 > #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 > #endif > > seurer@hogun:~/test/macro$ > ~buildbots/ppc64be-clang-test/clang-ppc64be/stage1/bin/clang++ -c t.C > t.C:7:2: error: LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 > #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 > ^ > 1 error generated. > seurer@hogun:~/test/macro$ ~/gcc/install/gcc-5.3.0/bin/g++ -c t.C > t.C:7:2: error: #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 > #error LLVM_THREADING_USE_STD_CALL_ONCE was set to 0 > ^ I mean, this is what I would expect. But given that, I can't explain the failure shown in the ppc64be build 2707 where it really seems to be throwing std::system_error out of the implementation of std::call_once.
So, any progress here? the BE build bot has been red for over a week at this point.
__ppc__ is not set on powerpc (at least not by the compiler). You should use __powerpc__ instead. When I looked at the preprocessor output of Threading.h LLVM_THREADING_USE_STD_CALL_ONCE is set to 1 because LLVM_ON_UNIX is also defined. In my little test it was not of course. Sorry that that caused confusion. I tried changing Threading.h locally to this #if defined(LLVM_ON_UNIX) && \ !(defined(__NetBSD__) && !defined(_LIBCPP_VERSION)) && !defined(__powerpc__) #define LLVM_THREADING_USE_STD_CALL_ONCE 1 #else #define LLVM_THREADING_USE_STD_CALL_ONCE 0 #endif So the #else will be what is used. When I built and ran the tests they all worked. The tests also work if I do not build with -DBUILD_SHARED_LIBS=ON even without changing Threading.h.
(In reply to comment #4) > __ppc__ is not set on powerpc (at least not by the compiler). You should > use __powerpc__ instead. So, I can change to __powerpc__, but I'm not really sure that's the right fix... You see, __ppc__ seems just as canonical as __powerpc__. For example this document suggests them equally: https://sourceforge.net/p/predef/wiki/Architectures/ And if you check the output of Clang itself, it defines both. And on the LE build bot, __ppc__ seems to work. So while we can change this, I suspect that roughly no one else in the world is aware that there exist some variants of toolchain and architecture that fail to define __ppc__ but do define __powerpc__. My personal suggestion would be to fix the compiler that omits __ppc__, but I'm also happy for you to try to update all the documentation and such to make it clear what the canonical macro should be. > > When I looked at the preprocessor output of Threading.h > LLVM_THREADING_USE_STD_CALL_ONCE is set to 1 because LLVM_ON_UNIX is also > defined. In my little test it was not of course. Sorry that that caused > confusion. > > I tried changing Threading.h locally to this > > #if defined(LLVM_ON_UNIX) && > \ > !(defined(__NetBSD__) && !defined(_LIBCPP_VERSION)) && > !defined(__powerpc__) > #define LLVM_THREADING_USE_STD_CALL_ONCE 1 > #else > #define LLVM_THREADING_USE_STD_CALL_ONCE 0 > #endif > > So the #else will be what is used. When I built and ran the tests they all > worked. Yes, that removes the confusion between the two build bots. But this bug is not about that. This bug is that I think PPC should not be checked here because it should have a working std::call_once implementation, and yet using the std;:call_once implementation causes pthread_once to fail. And more worrisomely it fails in different stages between the BE and LE build bot, and as you point out below, it starts working when using shared libraries. So there is some bug either in the PPC std::call_once implementation, or in the generated code by Clang for that implementation on PPC. That is what this bug is about. Essentially, you should be able to delete the "!defined(__powerpc__)" (or "!defined(__ppc__)" as it is currently spelled, and things *should* work, and the fact that they don't is a bug. > > The tests also work if I do not build with -DBUILD_SHARED_LIBS=ON even > without changing Threading.h.
From trying them out none of gcc 4.8, 4.9, 5.3, 6, nor 7 define __ppc__ on either BE or LE. clang though does. The ELFv2 ABI (Power Architecture 64-bit ELF V2 ABI Specification, OpenPOWER ABI for Linux Supplement) in Section 5.1.4, "Predefined Macros" shows that the defines are: __PPC__, __powerpc__, __PPC64__, __powerpc64__ The sourceforge.net document is in error. So it would appear that on LE the new code you added works and it is only on BE that it fails and the old way needs to be used until it is figured out what is wrong.
(In reply to comment #6) > From trying them out none of gcc 4.8, 4.9, 5.3, 6, nor 7 define __ppc__ on > either BE or LE. clang though does. > > The ELFv2 ABI (Power Architecture 64-bit ELF V2 ABI Specification, OpenPOWER > ABI for Linux Supplement) in Section 5.1.4, "Predefined Macros" shows that > the defines are: > > __PPC__, __powerpc__, __PPC64__, __powerpc64__ > > The sourceforge.net document is in error. Nice! glad that the spec actually calls out stuff here, that helps make it more clear. > > So it would appear that on LE the new code you added works and it is only on > BE that it fails and the old way needs to be used until it is figured out > what is wrong. Hah, not quite. Because it only was failing on LE during *stage 2*. But at that point, we're using Clang, and clang defines __ppc__...
(In reply to comment #7) > (In reply to comment #6) > > From trying them out none of gcc 4.8, 4.9, 5.3, 6, nor 7 define __ppc__ on > > either BE or LE. clang though does. > > > > The ELFv2 ABI (Power Architecture 64-bit ELF V2 ABI Specification, OpenPOWER > > ABI for Linux Supplement) in Section 5.1.4, "Predefined Macros" shows that > > the defines are: > > > > __PPC__, __powerpc__, __PPC64__, __powerpc64__ > > > > The sourceforge.net document is in error. > > Nice! glad that the spec actually calls out stuff here, that helps make it > more clear. > > > > > So it would appear that on LE the new code you added works and it is only on > > BE that it fails and the old way needs to be used until it is figured out > > what is wrong. > > Hah, not quite. Because it only was failing on LE during *stage 2*. But at > that point, we're using Clang, and clang defines __ppc__... (Also, wow, thanks for digging into this. My surprise is at how complex this is! I really appreciate you looking at what's going wrong here.)
(For fun btw there's this bit in gcc/config/rs6000/darwin.h: if (!TARGET_64BIT) builtin_define ("__ppc__"); \ so it'll get defined, but only for 32-bit there :)
(In reply to comment #7) > (In reply to comment #6) > Hah, not quite. Because it only was failing on LE during *stage 2*. But at > that point, we're using Clang, and clang defines __ppc__... My testing on PPC64-LE system showed that it was even failing in *stage 1*, if I build llvm/clang with -DBUILD_SHARED_LIBS=on. If I build with -DBUILD_SHARED_LIBS=off, then there were no failings in any stage.
This issue seems to have resurfaced in another thread. Should we change Threading.h as follows: Index: include/llvm/Support/Threading.h =================================================================== --- include/llvm/Support/Threading.h (revision 338649) +++ include/llvm/Support/Threading.h (working copy) @@ -27,7 +27,7 @@ #define LLVM_THREADING_USE_STD_CALL_ONCE 1 #elif defined(LLVM_ON_UNIX) && \ (defined(_LIBCPP_VERSION) || \ - !(defined(__NetBSD__) || defined(__OpenBSD__) || defined(__ppc__))) + !(defined(__NetBSD__) || defined(__OpenBSD__) || defined(__PPC__))) // std::call_once from libc++ is used on all Unix platforms. Other // implementations like libstdc++ are known to have problems on NetBSD, // OpenBSD and PowerPC.
Fixed quite awhile ago with 9b5fce1ce9af3b19101381bd0f9719f6ff35f709.