This is an archive of the discontinued LLVM Phabricator instance.

[libc][AArch64] Fix fullbuild when using G++/GCC
ClosedPublic

Authored by DavidSpickett on Feb 3 2023, 3:54 AM.

Details

Summary

The libc uses some functions that GCC does not currently
implement, that come from Arm's ACLE header usually.

These are:

__arm_wsr64
__arm_rsr64
__arm_wsr
__arm_rsr

This issue was reported to us (https://github.com/llvm/llvm-project/issues/60473)
and I've then reported that back to GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108642).

Even if these functions are added, clang has some non standard extensions
to them that gcc may not take. So we're looking at a fix in gcc 13 at best,
and that may not be enough for what we're doing with them.

So I've added ifdefs to use alternatives with gcc.

For handling the stack pointer, inline assembly is unfortunately the only option.
I have verified that the single mov is essentially what __arm_rsr64 generates.

For fpsr and fpcr the gcc devs suggested using
https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/AArch64-Built-in-Functions.html#AArch64-Built-in-Functions.

Diff Detail

Event Timeline

DavidSpickett created this revision.Feb 3 2023, 3:54 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptFeb 3 2023, 3:54 AM
DavidSpickett requested review of this revision.Feb 3 2023, 3:54 AM

I don't know what your policies on defines by compiler are, but this passes all tests on AArch64 Linux building with gcc 11.

If you don't want them then I'll instead note in the documentation that gcc is not supported for AArch64 for these reasons.

libc/src/__support/threads/linux/thread.cpp
221

This I maybe don't need volatile and might need to describe the side effects? If you're ok with inline asm here in general, I'll check if I need those.

DavidSpickett edited the summary of this revision. (Show Details)Feb 3 2023, 4:02 AM

I'm assuming any non clang is a gcc, going by https://libc.llvm.org/compiler_support.html.

If you know people are using non clang non gcc compilers I should refactor to check for gcc first, and otherwise do something else.

I'm assuming any non clang is a gcc, going by https://libc.llvm.org/compiler_support.html.

If you know people are using non clang non gcc compilers I should refactor to check for gcc first, and otherwise do something else.

I think we can safely assume non-clang implies GCC until we find a user with non-gcc/non-clang compiler trying to build the libc.

libc/src/__support/threads/linux/thread.cpp
221

Yes, this is OK. I am not an inline assembly expert, but I suspect you do need volatile (because the instruction is not touching any variables in C++), and that you don't need to describe side effects as it is clear that x29 is being updated. I will let you tell me what is the most appropriate thing to do here.

DavidSpickett marked an inline comment as done.EditedFeb 3 2023, 8:23 AM

Side note, I suspect that __arm_wsr64("x29", __arm_rsr64("sp")) could end up optimised out in some scenarios because clang doesn't see that it has a side effect, unlike a write to a sysreg. Checking a clang build, it is there so maybe I am wrong but I will do some more investigation.

Shouldn't block this though.

libc/src/__support/threads/linux/thread.cpp
221

Volatile is needed so the compiler doesn't move it about.

x29 (frame pointer) is set here so that in start_thread you can read the arguments. So in fact we don't want to tell the compiler that x29 is updated.

If we did it would save and restore the value around the statement and when we went to start thread, it would be incorrect.

DavidSpickett marked an inline comment as done.Feb 6 2023, 3:10 AM

Checking a clang build, it is there so maybe I am wrong but I will do some more investigation.

I looked into what this compiles down to and it turns out that with frame pointers on AArch64, there's always going to be a mov x29, sp somewhere before calling start_thread. Whether we add one or not. clang could remove the __arm_wsr64 call in some circumstances but in this one it does not. Even if it did remove it here, there would be another mov to achieve the same thing.

https://godbolt.org/z/6vK8GEvfj

1 extra instruction is not an issue, it documents what we're doing nicely and puts the mov nearer to the start_thread call for anyone (like me) who went looking for it.

sivachandra accepted this revision.Feb 16 2023, 8:32 AM
This revision is now accepted and ready to land.Feb 16 2023, 8:32 AM
This revision was automatically updated to reflect the committed changes.