-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[compiler-rt] Use __atomic builtins whenever possible #84439
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
[compiler-rt] Use __atomic builtins whenever possible #84439
Conversation
Created using spr 1.3.6-beta.1
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Alexander Richardson (arichardson) ChangesThe code in this file dates back to 2012 when Clang's support for atomic We also have to touch the non-clang codepaths here since the only way we Full diff: https://github.com/llvm/llvm-project/pull/84439.diff 6 Files Affected:
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Hi Alexander, Thanks for working on this. Please double-check that codegen for the following tsan functions in release builds don't change: __tsan_read1/2/4/8, __tsan_write1/2/4/8, __tsan_func_entry/exit. Please post diff of asm for these functions, if any. If we are refacatoring this, can we simplify code more today? I guess Vistual Studio does not support these buitlins, so we can't just switch to them. But perhaps we could switch to std::atomic? If yes, I would assume we still keep the atomic operation wrapper functions to minimize the diff. Also clang-format CI check complains, please re-format the code. |
Which architectures do you care about for these diffs? X86 should be easiest to generate, but I can also show AArch64, which might actually be better considering it has a weaker memory model? The reason I did not use std::atomic is that I was under the assumption that we can't rely on the C++ standard library here and have to roll our own. |
Also one more thing: this only touches the RMW operations, the loads/stores will require a separate patch that should allow for further simplification. |
x86 is good.
Yes, this may be the case. I think I will withdraw this part of my comment, let's just ensure there are no codegen degradation for the most important functions. |
To use the __atomic builtins and rely on libatomic for non-native atomics, you must do so consistently. You can't correctly mix-and-match RMW and load/store, or they might not be atomic with regards to each-other. That means:
|
Created using spr 1.3.6-beta.1
Created using spr 1.3.6-beta.1
On x86 I don't see any difference for __tsan_read*/__tsan_write* in the x86 assembly (other than the relative addresses). Same for __tsan_func_entry/exit. I do see one large diff. Code before:
After has a lot of extra stores:
It looks like the store mo_release loop was unrolled here if I read this correctly. |
I think you are right. There are 56 stores/movb in
|
Thanks for double checking. |
Thanks, that's probably why CI is failing (not sure why it didn't locally). |
Created using spr 1.3.6-beta.1
The code in this file dates back to 2012 when Clang's support for atomic
builtins was still quite limited. The bugs referenced in the comment
at the top of the file have long been fixed and using the compiler
builtins directly should now generate slightly better code.
Additionally, this allows using the atomic builtin header for platforms
where the __sync_builtins are lacking (e.g. Arm Morello).
This change does not introduce any code generation changes for
__tsan_read*/__tsan_write* or _tsan_func{entry,exit} on x86, which
indicates the previously noted compiler issues have been fixed.
We also have to touch the non-clang codepaths here since the only way we
can make this work easily is by making the memory_order enum match the
compiler-provided macros, so we have to update the debug checks that
assumed the enum was always a bitflag.
The one downside of this change is that 32-bit MIPS now definitely
requires libatomic (but that may already have been needed for RMW ops).