@@ -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::AtomicXchgOp::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__atomic_test_and_set: {
411493 auto op = cir::AtomicTestAndSetOp::create (
412494 builder, loc, ptr.getPointer (), order,
@@ -450,74 +532,50 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
450532 case AtomicExpr::AO__scoped_atomic_exchange_n:
451533 case AtomicExpr::AO__scoped_atomic_exchange:
452534
453- case AtomicExpr::AO__atomic_add_fetch:
454535 case AtomicExpr::AO__scoped_atomic_add_fetch:
455536
456- case AtomicExpr::AO__c11_atomic_fetch_add:
457537 case AtomicExpr::AO__hip_atomic_fetch_add:
458538 case AtomicExpr::AO__opencl_atomic_fetch_add:
459- case AtomicExpr::AO__atomic_fetch_add:
460539 case AtomicExpr::AO__scoped_atomic_fetch_add:
461540
462- case AtomicExpr::AO__atomic_sub_fetch:
463541 case AtomicExpr::AO__scoped_atomic_sub_fetch:
464542
465- case AtomicExpr::AO__c11_atomic_fetch_sub:
466543 case AtomicExpr::AO__hip_atomic_fetch_sub:
467544 case AtomicExpr::AO__opencl_atomic_fetch_sub:
468- case AtomicExpr::AO__atomic_fetch_sub:
469545 case AtomicExpr::AO__scoped_atomic_fetch_sub:
470546
471- case AtomicExpr::AO__atomic_min_fetch:
472547 case AtomicExpr::AO__scoped_atomic_min_fetch:
473548
474- case AtomicExpr::AO__c11_atomic_fetch_min:
475549 case AtomicExpr::AO__hip_atomic_fetch_min:
476550 case AtomicExpr::AO__opencl_atomic_fetch_min:
477- case AtomicExpr::AO__atomic_fetch_min:
478551 case AtomicExpr::AO__scoped_atomic_fetch_min:
479552
480- case AtomicExpr::AO__atomic_max_fetch:
481553 case AtomicExpr::AO__scoped_atomic_max_fetch:
482554
483- case AtomicExpr::AO__c11_atomic_fetch_max:
484555 case AtomicExpr::AO__hip_atomic_fetch_max:
485556 case AtomicExpr::AO__opencl_atomic_fetch_max:
486- case AtomicExpr::AO__atomic_fetch_max:
487557 case AtomicExpr::AO__scoped_atomic_fetch_max:
488558
489- case AtomicExpr::AO__atomic_and_fetch:
490559 case AtomicExpr::AO__scoped_atomic_and_fetch:
491560
492- case AtomicExpr::AO__c11_atomic_fetch_and:
493561 case AtomicExpr::AO__hip_atomic_fetch_and:
494562 case AtomicExpr::AO__opencl_atomic_fetch_and:
495- case AtomicExpr::AO__atomic_fetch_and:
496563 case AtomicExpr::AO__scoped_atomic_fetch_and:
497564
498- case AtomicExpr::AO__atomic_or_fetch:
499565 case AtomicExpr::AO__scoped_atomic_or_fetch:
500566
501- case AtomicExpr::AO__c11_atomic_fetch_or:
502567 case AtomicExpr::AO__hip_atomic_fetch_or:
503568 case AtomicExpr::AO__opencl_atomic_fetch_or:
504- case AtomicExpr::AO__atomic_fetch_or:
505569 case AtomicExpr::AO__scoped_atomic_fetch_or:
506570
507- case AtomicExpr::AO__atomic_xor_fetch:
508571 case AtomicExpr::AO__scoped_atomic_xor_fetch:
509572
510- case AtomicExpr::AO__c11_atomic_fetch_xor:
511573 case AtomicExpr::AO__hip_atomic_fetch_xor:
512574 case AtomicExpr::AO__opencl_atomic_fetch_xor:
513- case AtomicExpr::AO__atomic_fetch_xor:
514575 case AtomicExpr::AO__scoped_atomic_fetch_xor:
515576
516- case AtomicExpr::AO__atomic_nand_fetch:
517577 case AtomicExpr::AO__scoped_atomic_nand_fetch:
518578
519- case AtomicExpr::AO__c11_atomic_fetch_nand:
520- case AtomicExpr::AO__atomic_fetch_nand:
521579 case AtomicExpr::AO__scoped_atomic_fetch_nand:
522580 cgf.cgm .errorNYI (expr->getSourceRange (), " emitAtomicOp: expr op NYI" );
523581 return ;
@@ -531,9 +589,13 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
531589 mlir::Operation *rmwOp = builder.create (loc, builder.getStringAttr (opName),
532590 atomicOperands, atomicResTys);
533591
592+ if (fetchAttr)
593+ rmwOp->setAttr (" binop" , fetchAttr);
534594 rmwOp->setAttr (" mem_order" , orderAttr);
535595 if (expr->isVolatile ())
536596 rmwOp->setAttr (" is_volatile" , builder.getUnitAttr ());
597+ if (fetchFirst && opName == cir::AtomicFetchOp::getOperationName ())
598+ rmwOp->setAttr (" fetch_first" , builder.getUnitAttr ());
537599
538600 mlir::Value result = rmwOp->getResult (0 );
539601 builder.createStore (loc, result, dest);
@@ -629,8 +691,41 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
629691 isWeakExpr = e->getWeak ();
630692 break ;
631693
694+ case AtomicExpr::AO__c11_atomic_fetch_add:
695+ case AtomicExpr::AO__c11_atomic_fetch_sub:
696+ if (memTy->isPointerType ()) {
697+ cgm.errorNYI (e->getSourceRange (),
698+ " atomic fetch-and-add and fetch-and-sub for pointers" );
699+ return RValue::get (nullptr );
700+ }
701+ [[fallthrough]];
702+ case AtomicExpr::AO__atomic_fetch_add:
703+ case AtomicExpr::AO__atomic_fetch_max:
704+ case AtomicExpr::AO__atomic_fetch_min:
705+ case AtomicExpr::AO__atomic_fetch_sub:
706+ case AtomicExpr::AO__atomic_add_fetch:
707+ case AtomicExpr::AO__atomic_max_fetch:
708+ case AtomicExpr::AO__atomic_min_fetch:
709+ case AtomicExpr::AO__atomic_sub_fetch:
710+ case AtomicExpr::AO__c11_atomic_fetch_max:
711+ case AtomicExpr::AO__c11_atomic_fetch_min:
712+ shouldCastToIntPtrTy = !memTy->isFloatingType ();
713+ [[fallthrough]];
714+
715+ case AtomicExpr::AO__atomic_fetch_and:
716+ case AtomicExpr::AO__atomic_fetch_nand:
717+ case AtomicExpr::AO__atomic_fetch_or:
718+ case AtomicExpr::AO__atomic_fetch_xor:
719+ case AtomicExpr::AO__atomic_and_fetch:
720+ case AtomicExpr::AO__atomic_nand_fetch:
721+ case AtomicExpr::AO__atomic_or_fetch:
722+ case AtomicExpr::AO__atomic_xor_fetch:
632723 case AtomicExpr::AO__atomic_exchange_n:
633724 case AtomicExpr::AO__atomic_store_n:
725+ case AtomicExpr::AO__c11_atomic_fetch_and:
726+ case AtomicExpr::AO__c11_atomic_fetch_nand:
727+ case AtomicExpr::AO__c11_atomic_fetch_or:
728+ case AtomicExpr::AO__c11_atomic_fetch_xor:
634729 case AtomicExpr::AO__c11_atomic_exchange:
635730 case AtomicExpr::AO__c11_atomic_store:
636731 val1 = emitValToTemp (*this , e->getVal1 ());
0 commit comments