@@ -346,6 +346,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
346346 CIRGenBuilderTy &builder = cgf.getBuilder ();
347347 mlir::Location loc = cgf.getLoc (expr->getSourceRange ());
348348 auto orderAttr = cir::MemOrderAttr::get (builder.getContext (), order);
349+ cir::AtomicFetchKindAttr fetchAttr;
350+ bool fetchFirst = true ;
349351
350352 switch (expr->getOp ()) {
351353 case AtomicExpr::AO__c11_atomic_init:
@@ -407,6 +409,86 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
407409 opName = cir::AtomicXchg::getOperationName ();
408410 break ;
409411
412+ case AtomicExpr::AO__atomic_add_fetch:
413+ fetchFirst = false ;
414+ [[fallthrough]];
415+ case AtomicExpr::AO__c11_atomic_fetch_add:
416+ case AtomicExpr::AO__atomic_fetch_add:
417+ opName = cir::AtomicFetchOp::getOperationName ();
418+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
419+ cir::AtomicFetchKind::Add);
420+ break ;
421+
422+ case AtomicExpr::AO__atomic_sub_fetch:
423+ fetchFirst = false ;
424+ [[fallthrough]];
425+ case AtomicExpr::AO__c11_atomic_fetch_sub:
426+ case AtomicExpr::AO__atomic_fetch_sub:
427+ opName = cir::AtomicFetchOp::getOperationName ();
428+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
429+ cir::AtomicFetchKind::Sub);
430+ break ;
431+
432+ case AtomicExpr::AO__atomic_min_fetch:
433+ fetchFirst = false ;
434+ [[fallthrough]];
435+ case AtomicExpr::AO__c11_atomic_fetch_min:
436+ case AtomicExpr::AO__atomic_fetch_min:
437+ opName = cir::AtomicFetchOp::getOperationName ();
438+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
439+ cir::AtomicFetchKind::Min);
440+ break ;
441+
442+ case AtomicExpr::AO__atomic_max_fetch:
443+ fetchFirst = false ;
444+ [[fallthrough]];
445+ case AtomicExpr::AO__c11_atomic_fetch_max:
446+ case AtomicExpr::AO__atomic_fetch_max:
447+ opName = cir::AtomicFetchOp::getOperationName ();
448+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
449+ cir::AtomicFetchKind::Max);
450+ break ;
451+
452+ case AtomicExpr::AO__atomic_and_fetch:
453+ fetchFirst = false ;
454+ [[fallthrough]];
455+ case AtomicExpr::AO__c11_atomic_fetch_and:
456+ case AtomicExpr::AO__atomic_fetch_and:
457+ opName = cir::AtomicFetchOp::getOperationName ();
458+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
459+ cir::AtomicFetchKind::And);
460+ break ;
461+
462+ case AtomicExpr::AO__atomic_or_fetch:
463+ fetchFirst = false ;
464+ [[fallthrough]];
465+ case AtomicExpr::AO__c11_atomic_fetch_or:
466+ case AtomicExpr::AO__atomic_fetch_or:
467+ opName = cir::AtomicFetchOp::getOperationName ();
468+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
469+ cir::AtomicFetchKind::Or);
470+ break ;
471+
472+ case AtomicExpr::AO__atomic_xor_fetch:
473+ fetchFirst = false ;
474+ [[fallthrough]];
475+ case AtomicExpr::AO__c11_atomic_fetch_xor:
476+ case AtomicExpr::AO__atomic_fetch_xor:
477+ opName = cir::AtomicFetchOp::getOperationName ();
478+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
479+ cir::AtomicFetchKind::Xor);
480+ break ;
481+
482+ case AtomicExpr::AO__atomic_nand_fetch:
483+ fetchFirst = false ;
484+ [[fallthrough]];
485+ case AtomicExpr::AO__c11_atomic_fetch_nand:
486+ case AtomicExpr::AO__atomic_fetch_nand:
487+ opName = cir::AtomicFetchOp::getOperationName ();
488+ fetchAttr = cir::AtomicFetchKindAttr::get (builder.getContext (),
489+ cir::AtomicFetchKind::Nand);
490+ break ;
491+
410492 case AtomicExpr::AO__opencl_atomic_init:
411493
412494 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
@@ -433,74 +515,50 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
433515 case AtomicExpr::AO__scoped_atomic_exchange_n:
434516 case AtomicExpr::AO__scoped_atomic_exchange:
435517
436- case AtomicExpr::AO__atomic_add_fetch:
437518 case AtomicExpr::AO__scoped_atomic_add_fetch:
438519
439- case AtomicExpr::AO__c11_atomic_fetch_add:
440520 case AtomicExpr::AO__hip_atomic_fetch_add:
441521 case AtomicExpr::AO__opencl_atomic_fetch_add:
442- case AtomicExpr::AO__atomic_fetch_add:
443522 case AtomicExpr::AO__scoped_atomic_fetch_add:
444523
445- case AtomicExpr::AO__atomic_sub_fetch:
446524 case AtomicExpr::AO__scoped_atomic_sub_fetch:
447525
448- case AtomicExpr::AO__c11_atomic_fetch_sub:
449526 case AtomicExpr::AO__hip_atomic_fetch_sub:
450527 case AtomicExpr::AO__opencl_atomic_fetch_sub:
451- case AtomicExpr::AO__atomic_fetch_sub:
452528 case AtomicExpr::AO__scoped_atomic_fetch_sub:
453529
454- case AtomicExpr::AO__atomic_min_fetch:
455530 case AtomicExpr::AO__scoped_atomic_min_fetch:
456531
457- case AtomicExpr::AO__c11_atomic_fetch_min:
458532 case AtomicExpr::AO__hip_atomic_fetch_min:
459533 case AtomicExpr::AO__opencl_atomic_fetch_min:
460- case AtomicExpr::AO__atomic_fetch_min:
461534 case AtomicExpr::AO__scoped_atomic_fetch_min:
462535
463- case AtomicExpr::AO__atomic_max_fetch:
464536 case AtomicExpr::AO__scoped_atomic_max_fetch:
465537
466- case AtomicExpr::AO__c11_atomic_fetch_max:
467538 case AtomicExpr::AO__hip_atomic_fetch_max:
468539 case AtomicExpr::AO__opencl_atomic_fetch_max:
469- case AtomicExpr::AO__atomic_fetch_max:
470540 case AtomicExpr::AO__scoped_atomic_fetch_max:
471541
472- case AtomicExpr::AO__atomic_and_fetch:
473542 case AtomicExpr::AO__scoped_atomic_and_fetch:
474543
475- case AtomicExpr::AO__c11_atomic_fetch_and:
476544 case AtomicExpr::AO__hip_atomic_fetch_and:
477545 case AtomicExpr::AO__opencl_atomic_fetch_and:
478- case AtomicExpr::AO__atomic_fetch_and:
479546 case AtomicExpr::AO__scoped_atomic_fetch_and:
480547
481- case AtomicExpr::AO__atomic_or_fetch:
482548 case AtomicExpr::AO__scoped_atomic_or_fetch:
483549
484- case AtomicExpr::AO__c11_atomic_fetch_or:
485550 case AtomicExpr::AO__hip_atomic_fetch_or:
486551 case AtomicExpr::AO__opencl_atomic_fetch_or:
487- case AtomicExpr::AO__atomic_fetch_or:
488552 case AtomicExpr::AO__scoped_atomic_fetch_or:
489553
490- case AtomicExpr::AO__atomic_xor_fetch:
491554 case AtomicExpr::AO__scoped_atomic_xor_fetch:
492555
493- case AtomicExpr::AO__c11_atomic_fetch_xor:
494556 case AtomicExpr::AO__hip_atomic_fetch_xor:
495557 case AtomicExpr::AO__opencl_atomic_fetch_xor:
496- case AtomicExpr::AO__atomic_fetch_xor:
497558 case AtomicExpr::AO__scoped_atomic_fetch_xor:
498559
499- case AtomicExpr::AO__atomic_nand_fetch:
500560 case AtomicExpr::AO__scoped_atomic_nand_fetch:
501561
502- case AtomicExpr::AO__c11_atomic_fetch_nand:
503- case AtomicExpr::AO__atomic_fetch_nand:
504562 case AtomicExpr::AO__scoped_atomic_fetch_nand:
505563
506564 case AtomicExpr::AO__atomic_test_and_set:
@@ -518,9 +576,13 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
518576 mlir::Operation *rmwOp = builder.create (loc, builder.getStringAttr (opName),
519577 atomicOperands, atomicResTys);
520578
579+ if (fetchAttr)
580+ rmwOp->setAttr (" binop" , fetchAttr);
521581 rmwOp->setAttr (" mem_order" , orderAttr);
522582 if (expr->isVolatile ())
523583 rmwOp->setAttr (" is_volatile" , builder.getUnitAttr ());
584+ if (fetchFirst && opName == cir::AtomicFetchOp::getOperationName ())
585+ rmwOp->setAttr (" fetch_first" , builder.getUnitAttr ());
524586
525587 mlir::Value result = rmwOp->getResult (0 );
526588 builder.createStore (loc, result, dest);
@@ -614,8 +676,41 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
614676 isWeakExpr = e->getWeak ();
615677 break ;
616678
679+ case AtomicExpr::AO__c11_atomic_fetch_add:
680+ case AtomicExpr::AO__c11_atomic_fetch_sub:
681+ if (memTy->isPointerType ()) {
682+ cgm.errorNYI (e->getSourceRange (),
683+ " atomic fetch-and-add and fetch-and-sub for pointers" );
684+ return RValue::get (nullptr );
685+ }
686+ [[fallthrough]];
687+ case AtomicExpr::AO__atomic_fetch_add:
688+ case AtomicExpr::AO__atomic_fetch_max:
689+ case AtomicExpr::AO__atomic_fetch_min:
690+ case AtomicExpr::AO__atomic_fetch_sub:
691+ case AtomicExpr::AO__atomic_add_fetch:
692+ case AtomicExpr::AO__atomic_max_fetch:
693+ case AtomicExpr::AO__atomic_min_fetch:
694+ case AtomicExpr::AO__atomic_sub_fetch:
695+ case AtomicExpr::AO__c11_atomic_fetch_max:
696+ case AtomicExpr::AO__c11_atomic_fetch_min:
697+ shouldCastToIntPtrTy = !memTy->isFloatingType ();
698+ [[fallthrough]];
699+
700+ case AtomicExpr::AO__atomic_fetch_and:
701+ case AtomicExpr::AO__atomic_fetch_nand:
702+ case AtomicExpr::AO__atomic_fetch_or:
703+ case AtomicExpr::AO__atomic_fetch_xor:
704+ case AtomicExpr::AO__atomic_and_fetch:
705+ case AtomicExpr::AO__atomic_nand_fetch:
706+ case AtomicExpr::AO__atomic_or_fetch:
707+ case AtomicExpr::AO__atomic_xor_fetch:
617708 case AtomicExpr::AO__atomic_exchange_n:
618709 case AtomicExpr::AO__atomic_store_n:
710+ case AtomicExpr::AO__c11_atomic_fetch_and:
711+ case AtomicExpr::AO__c11_atomic_fetch_nand:
712+ case AtomicExpr::AO__c11_atomic_fetch_or:
713+ case AtomicExpr::AO__c11_atomic_fetch_xor:
619714 case AtomicExpr::AO__c11_atomic_exchange:
620715 case AtomicExpr::AO__c11_atomic_store:
621716 val1 = emitValToTemp (*this , e->getVal1 ());
0 commit comments