[clang] [libcxx] [Clang] Support atomic operations on _BitInt(N) (PR #204815)

Xavier Roche via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 26 23:45:15 PDT 2026


================
@@ -1109,6 +1299,27 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
   LValue AtomicVal = MakeAddrLValue(Ptr, AtomicTy);
   AtomicInfo Atomics(*this, AtomicVal);
 
+  // A `_BitInt(N)` read-modify-write whose value width has padding bits, or
+  // whose size forces a libcall, cannot use a single atomicrmw: the op would
+  // carry into / compare the padding bits, and no arbitrary-width
+  // __atomic_fetch_* libcall exists. Emit a compare-exchange loop instead.
+  // Bitwise and/or/xor are exact even with padding, so only the wide case needs
+  // the loop for them. load/store/exchange/compare_exchange keep their paths.
+  if (MemTy->isBitIntType()) {
+    llvm::AtomicRMWInst::BinOp BinOp;
+    bool RMWReturnsNew;
+    if (classifyBitIntRMW(E->getOp(), MemTy->isSignedIntegerType(), BinOp,
+                          RMWReturnsNew)) {
+      bool WideOrNonPow2 = (Size & (Size - 1)) != 0 || Size > 16;
----------------
xroche wrote:

Edit: Why not just emit the simple atomic and let the backend handle it ?

For ordinary 64/128-bit sizes we already do. The hand-written loop is only for two cases the single instruction can't handle: odd sizes (37 bits), where it would corrupt the padding bits, and sizes over 128 bits, where no hardware instruction or ready-made library add exists.

https://github.com/llvm/llvm-project/pull/204815


More information about the cfe-commits mailing list