@@ -341,6 +341,7 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
341341 }
342342
343343 assert (!cir::MissingFeatures::atomicSyncScopeID ());
344+ llvm::StringRef opName;
344345
345346 CIRGenBuilderTy &builder = cgf.getBuilder ();
346347 mlir::Location loc = cgf.getLoc (expr->getSourceRange ());
@@ -400,6 +401,12 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
400401 return ;
401402 }
402403
404+ case AtomicExpr::AO__c11_atomic_exchange:
405+ case AtomicExpr::AO__atomic_exchange_n:
406+ case AtomicExpr::AO__atomic_exchange:
407+ opName = cir::AtomicXchg::getOperationName ();
408+ break ;
409+
403410 case AtomicExpr::AO__opencl_atomic_init:
404411
405412 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
@@ -421,11 +428,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
421428 case AtomicExpr::AO__scoped_atomic_store:
422429 case AtomicExpr::AO__scoped_atomic_store_n:
423430
424- case AtomicExpr::AO__c11_atomic_exchange:
425431 case AtomicExpr::AO__hip_atomic_exchange:
426432 case AtomicExpr::AO__opencl_atomic_exchange:
427- case AtomicExpr::AO__atomic_exchange_n:
428- case AtomicExpr::AO__atomic_exchange:
429433 case AtomicExpr::AO__scoped_atomic_exchange_n:
430434 case AtomicExpr::AO__scoped_atomic_exchange:
431435
@@ -503,8 +507,23 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
503507
504508 case AtomicExpr::AO__atomic_clear:
505509 cgf.cgm .errorNYI (expr->getSourceRange (), " emitAtomicOp: expr op NYI" );
506- break ;
510+ return ;
507511 }
512+
513+ assert (!opName.empty () && " expected operation name to build" );
514+ mlir::Value loadVal1 = builder.createLoad (loc, val1);
515+
516+ SmallVector<mlir::Value> atomicOperands = {ptr.getPointer (), loadVal1};
517+ SmallVector<mlir::Type> atomicResTys = {loadVal1.getType ()};
518+ mlir::Operation *rmwOp = builder.create (loc, builder.getStringAttr (opName),
519+ atomicOperands, atomicResTys);
520+
521+ rmwOp->setAttr (" mem_order" , orderAttr);
522+ if (expr->isVolatile ())
523+ rmwOp->setAttr (" is_volatile" , builder.getUnitAttr ());
524+
525+ mlir::Value result = rmwOp->getResult (0 );
526+ builder.createStore (loc, result, dest);
508527}
509528
510529static bool isMemOrderValid (uint64_t order, bool isStore, bool isLoad) {
@@ -572,6 +591,11 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
572591 val1 = emitPointerWithAlignment (e->getVal1 ());
573592 break ;
574593
594+ case AtomicExpr::AO__atomic_exchange:
595+ val1 = emitPointerWithAlignment (e->getVal1 ());
596+ dest = emitPointerWithAlignment (e->getVal2 ());
597+ break ;
598+
575599 case AtomicExpr::AO__atomic_compare_exchange:
576600 case AtomicExpr::AO__atomic_compare_exchange_n:
577601 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
@@ -590,7 +614,9 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
590614 isWeakExpr = e->getWeak ();
591615 break ;
592616
617+ case AtomicExpr::AO__atomic_exchange_n:
593618 case AtomicExpr::AO__atomic_store_n:
619+ case AtomicExpr::AO__c11_atomic_exchange:
594620 case AtomicExpr::AO__c11_atomic_store:
595621 val1 = emitValToTemp (*this , e->getVal1 ());
596622 break ;
0 commit comments