================
@@ -247,6 +247,78 @@ static RValue emitBinaryAtomicPost(CIRGenFunction &cgf,
return RValue::get(result);
}
+/// Emit a `cir.atomic.cmpxchg` for __sync_val_compare_and_swap_N.
+/// Returns the old value (type matches the pointee of ptr).
+static mlir::Value emitAtomicCmpXchgValue(CIRGenFunction &cgf,
+ const CallExpr *e,
+ cir::MemOrder succOrder,
+ cir::MemOrder failOrder) {
+ Address destAddr = checkAtomicAlignment(cgf, e);
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+ mlir::Value destValue = destAddr.emitRawPointer();
+ mlir::Value expected = cgf.emitScalarExpr(e->getArg(1));
+ mlir::Value desired = cgf.emitScalarExpr(e->getArg(2));
+
+ auto cmpxchg = cir::AtomicCmpXchgOp::create(
+ builder, cgf.getLoc(e->getSourceRange()), destValue, expected, desired,
+ succOrder, failOrder, cir::SyncScopeKind::System,
+ /*alignment=*/nullptr, /*weak=*/false, /*is_volatile=*/false);
+ return cmpxchg.getOld();
+}
+
+/// Emit a `cir.atomic.cmpxchg` for __sync_bool_compare_and_swap_N.
+/// Returns a boolean: true if the exchange succeeded.
+static RValue emitAtomicCmpXchgBool(CIRGenFunction &cgf, const CallExpr *e) {
+ Address destAddr = checkAtomicAlignment(cgf, e);
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+ mlir::Value destValue = destAddr.emitRawPointer();
+ mlir::Value expected = cgf.emitScalarExpr(e->getArg(1));
+ mlir::Value desired = cgf.emitScalarExpr(e->getArg(2));
+
+ auto cmpxchg = cir::AtomicCmpXchgOp::create(
+ builder, cgf.getLoc(e->getSourceRange()), destValue, expected, desired,
+ cir::MemOrder::SequentiallyConsistent,
+ cir::MemOrder::SequentiallyConsistent, cir::SyncScopeKind::System,
+ /*alignment=*/nullptr, /*weak=*/false, /*is_volatile=*/false);
+
+ // cir.atomic.cmpxchg already returns (old, success). Use the success
+ // flag directly instead of re-emitting getArg(1) and comparing.
+ mlir::Value success = cmpxchg.getSuccess();
+ mlir::Value result =
+ builder.createIntCast(success, cgf.convertType(e->getType()));
+ return RValue::get(result);
+}
+
+/// Emit a `cir.atomic.xchg` for __sync_swap_N and __sync_lock_test_and_set_N.
+static mlir::Value emitAtomicXchg(CIRGenFunction &cgf, const CallExpr *e,
----------------
Lancern wrote:
Why return `mlir::Value` instead of `RValue`?
https://github.com/llvm/llvm-project/pull/214606
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits