Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ppc64 (be and le) don't have a working std::call_once #28398

Closed
chandlerc opened this issue Jun 6, 2016 · 13 comments
Closed

ppc64 (be and le) don't have a working std::call_once #28398

chandlerc opened this issue Jun 6, 2016 · 13 comments
Labels
bugzilla Issues migrated from bugzilla llvm:core

Comments

@chandlerc
Copy link
Member

Bugzilla Link 28024
Resolution FIXED
Resolved on Aug 27, 2020 14:00
Version trunk
OS All
CC @echristo,@ecnelises,@hfinkel,@nemanjai

Extended Description

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 6, 2016

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
^

@chandlerc
Copy link
Member Author

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.

@chandlerc
Copy link
Member Author

So, any progress here? the BE build bot has been red for over a week at this point.

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 15, 2016

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.

@chandlerc
Copy link
Member Author

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 15, 2016

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.

@chandlerc
Copy link
Member Author

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...

@chandlerc
Copy link
Member Author

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.)

1 similar comment
@chandlerc
Copy link
Member Author

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.)

@echristo
Copy link
Contributor

(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 :)

@llvmbot
Copy link
Collaborator

llvmbot commented Jun 15, 2016

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.

@nemanjai
Copy link
Member

nemanjai commented Aug 8, 2018

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.

@llvmbot
Copy link
Collaborator

llvmbot commented Aug 27, 2020

Fixed quite awhile ago with 9b5fce1.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla llvm:core
Projects
None yet
Development

No branches or pull requests

4 participants