-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
MDEV-36217: Fix building with Clang and GCC on RISC-V #3871
base: 10.6
Are you sure you want to change the base?
Conversation
Thanks @brad0 , @dr-m is looking at it in MDEV-36217. Which instruction is this byte sequence mapping to? |
As was mentioned in the original commit.. Use raw instruction encoding, no idea how to cleanly access the pause instruction from the Zihintpause extension. Just FYI this is on OpenBSD with Clang 16. |
include/my_cpu.h
Outdated
#ifdef __clang__ | ||
__asm__ volatile(".long 0x0100000f" ::: "memory"); | ||
#else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I tested my take at this in (see my comment in MDEV-36217) I did confirm that this is the encoding of the instruction on both 32-bit and 64-bit RISC-V. I kind of like the simplicity and the portability of this, but not the readability (or the lack thereof). As far as I understand, this version would work practically with any version of GCC (and underlying assembler) or clang
. If we go down this route, I’d suggest a verbose comment:
#elif defined __GNUC__ && defined __riscv
/* The GCC-only __builtin_riscv_pause() or the pause instruction is
encoded like a fence instruction with special parameters. On RISC-V
implementations that do not support arch=+zihintpause this
instruction could be interpreted as a more expensive memory fence;
it should not be an illegal instruction. */
__asm__ volatile(".long 0x0100000f" ::: "memory");
#elif defined __GNUC__
I don’t have a RISC-V system to test on, so my "less hacky" version would have to be tested by you (clang) and @ottok (GCC on Ubuntu). I expect that some additional changes would be necessary. The __attribute__((target("arch=+zihintpause")))
that my fix would add to this inline
function would have to be added to each function that invokes this, similar to the TRANSACTIONAL_INLINE
and TRANSACTIONAL_TARGET
that are defined for the Intel TSX-NI (rtm
) ISA extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind testing anything no matter which direction we go in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I should have read all the discussion before looking at the code. Given that you are on clang 16, my "less hacky" approach is not going to work, because the inline assembler would only know about fence
starting with clang 18. Let’s go with your version, but please apply the comment change that I suggested. I hope that @ottok can schedule this on the Ubuntu CI as soon as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also to note as an LLVM/Clang developer I opened a ticket upstream to see about adding the builtin to Clang. Not that it helps now but it's good to push for feature parity when missing bits.
Will do.
Clang does not have the builtin __builtin_riscv_pause(). Forwarded: MariaDB#3871
I am now testing this fix in https://salsa.debian.org/mariadb-team/mariadb-server/-/merge_requests/108 and will post results in a couple of hours. |
|
The initial diff was only for Clang. Try the updated diff I just pushed. |
include/my_cpu.h
Outdated
# if !defined(__clang__) && __GNUC__ >= 14 | ||
__builtin_riscv_pause(); | ||
# else | ||
__asm__ volatile(".long 0x0100000f" ::: "memory"); | ||
# endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on my test on https://godbolt.org this will not work on GCC 14. We’d need to specify __attribute__((target("arch=+zihintpause")))
on the function and any function that invokes it inline. By the way, I believe that clang always defines __GNUC__
as 4, and you’re evaluating __GNUC__
without checking that it’s defined.
I think that we should simply use the numeric encoding of the instruction for both GCC and clang, no matter which version. You should also remove the word "older" from the title of this pull request, because the existing code only happens to work with exactly GCC 13 (but likely not with its assembler invocation), not GCC 14 or anything newer.
I believe that the .long 0x0100000f
should work with practically any version of clang or GCC or assembler that targets RISC-V. The built-in function does not exist in clang, but starting with clang-18 the inline assembler would recognize the pause
instruction. That would not help you, because you’re using clang version 16.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used older as I was under the impression that fairly modern versions were Ok. Now I understand your post above.
Not that it matters with the updated diff, but it checks if __GNUC__
is defined right above that.
Clang does not have the builtin __builtin_riscv_pause().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I would wait for results from @ottok before merging this.
Clang does not have the builtin __builtin_riscv_pause(). Forwarded: MariaDB#3871
I tried a different variation at and the build fully passed https://launchpad.net/~mysql-ubuntu/+archive/ubuntu/mariadb/+build/30402143 3 minutes ago: diff --git a/include/my_cpu.h b/include/my_cpu.h
index bd5fca5..f68558a 100644
--- a/include/my_cpu.h
+++ b/include/my_cpu.h
@@ -97,7 +97,16 @@ static inline void MY_RELAX_CPU(void)
/* Changed from __ppc_get_timebase for musl and clang compatibility */
__builtin_ppc_get_timebase();
#elif defined __GNUC__ && defined __riscv
- __builtin_riscv_pause();
+ /* The GCC-only __builtin_riscv_pause() or the pause instruction is
+ encoded like a fence instruction with special parameters. On RISC-V
+ implementations that do not support arch=+zihintpause this
+ instruction could be interpreted as a more expensive memory fence;
+ it should not be an illegal instruction. */
+#ifdef __builtin_riscv_pause
+ __builtin_riscv_pause();
+#else
+ __asm__ volatile(".long 0x0100000f" ::: "memory");
+#endif
#elif defined __GNUC__
/* Mainly, prevent the compiler from optimizing away delay loops */
__asm__ __volatile__ ("":::"memory"); I will re-build now with the latest version of this PR#3871. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ottok Thank you! Is there also a log of running some regression tests, so that we would see the runtime behaviour? |
Right, I forced the MTR to run now post-build and it all passed in https://launchpadlibrarian.net/780866991/buildlog_ubuntu-jammy-riscv64.mariadb-10.6_1%3A10.6.21-0ubuntu0.22.04.1~bpo22.04.1~1741455135.68ead9769b1+bugfix.10.6.fix.riscv64.build_BUILDING.txt.gz
|
Clang does not have the builtin __builtin_riscv_pause(). Forwarded: MariaDB#3871
Clang does not have the builtin __builtin_riscv_pause(). Forwarded: MariaDB#3871
This is pending being included for the Ubuntu 24.10 upload at https://salsa.debian.org/mariadb-team/mariadb-server/-/merge_requests/109 |
@vuvova Ping. |
Description
Clang does not have the builtin __builtin_riscv_pause().
Release Notes
Fix building with Clang and GCC (other than 13) on RISC-V
How can this PR be tested?
Build test with Clang and GCC (other than 13).
Basing the PR against the correct MariaDB version
main
branch.PR quality check