[clang] [CIR] Implement 'simple' atomic inc/dec. (PR #222730)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 11 11:58:58 PDT 2026


================
@@ -628,10 +628,88 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
     mlir::Value value;
     mlir::Value input;
 
-    if (type->getAs<AtomicType>()) {
+    if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
+      QualType valType = atomicTy->getValueType();
+      mlir::Location loc = cgf.getLoc(e->getSourceRange());
+      bool isInc = e->isIncrementOp();
+      bool isPre = e->isPrefix();
+
+      // Bools are always set-to-true, as decrement isn't legal on bools.
+      if (valType->isBooleanType()) {
+        assert(isInc);
+        // Atomic operations require an integer type; reinterpret the bool
+        // pointer as a pointer to its underlying storage integer type.
+        cir::IntType intTy = builder.getUInt8Ty();
+        mlir::Value one = builder.getConstInt(loc, intTy, 1);
+        Address intAddr = lv.getAddress().withElementType(builder, intTy);
+
+        if (isPre) {
+          // Pre-increment: atomically store true, return true.
+          cir::StoreOp store = builder.createStore(loc, one, intAddr);
+          store.setMemOrder(cir::MemOrder::SequentiallyConsistent);
+          if (lv.isVolatileQualified())
+            store.setIsVolatile(true);
+          return builder.getTrue(loc);
+        }
+        // Post-increment: atomically exchange with true, return old value.
+        auto xchg = cir::AtomicXchgOp::create(
+            builder, loc, intAddr.getPointer(), one,
+            cir::MemOrder::SequentiallyConsistent, cir::SyncScopeKind::System,
+            lv.isVolatileQualified());
+        return builder.createCast(cir::CastKind::int_to_bool, xchg.getResult(),
+                                  builder.getBoolTy());
+      }
+
+      // Special case for atomic increment / decrement on integers, emit
+      // atomicrmw instructions.  We skip this if we want to be doing overflow
+      // checking, and fall into the slow path with the atomic cmpxchg loop.
+      if (!valType->isBooleanType() && valType->isIntegerType() &&
----------------
erichkeane wrote:

Nope, and I removed it at one point :)  I ended up wanting to pick up the below sanitizer option exactly, so cheated and copy/pasted so I got this back :/ 

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


More information about the cfe-commits mailing list