@@ -346,6 +346,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
346
346
CIRGenBuilderTy &builder = cgf.getBuilder ();
347
347
mlir::Location loc = cgf.getLoc (expr->getSourceRange ());
348
348
auto orderAttr = cir::MemOrderAttr::get (builder.getContext (), order);
349
+ cir::AtomicFetchKindAttr fetchAttr;
350
+ bool fetchFirst = true ;
349
351
350
352
switch (expr->getOp ()) {
351
353
case AtomicExpr::AO__c11_atomic_init:
@@ -407,6 +409,86 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
407
409
opName = cir::AtomicXchg::getOperationName ();
408
410
break ;
409
411
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
+
410
492
case AtomicExpr::AO__opencl_atomic_init:
411
493
412
494
case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
@@ -433,74 +515,50 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
433
515
case AtomicExpr::AO__scoped_atomic_exchange_n:
434
516
case AtomicExpr::AO__scoped_atomic_exchange:
435
517
436
- case AtomicExpr::AO__atomic_add_fetch:
437
518
case AtomicExpr::AO__scoped_atomic_add_fetch:
438
519
439
- case AtomicExpr::AO__c11_atomic_fetch_add:
440
520
case AtomicExpr::AO__hip_atomic_fetch_add:
441
521
case AtomicExpr::AO__opencl_atomic_fetch_add:
442
- case AtomicExpr::AO__atomic_fetch_add:
443
522
case AtomicExpr::AO__scoped_atomic_fetch_add:
444
523
445
- case AtomicExpr::AO__atomic_sub_fetch:
446
524
case AtomicExpr::AO__scoped_atomic_sub_fetch:
447
525
448
- case AtomicExpr::AO__c11_atomic_fetch_sub:
449
526
case AtomicExpr::AO__hip_atomic_fetch_sub:
450
527
case AtomicExpr::AO__opencl_atomic_fetch_sub:
451
- case AtomicExpr::AO__atomic_fetch_sub:
452
528
case AtomicExpr::AO__scoped_atomic_fetch_sub:
453
529
454
- case AtomicExpr::AO__atomic_min_fetch:
455
530
case AtomicExpr::AO__scoped_atomic_min_fetch:
456
531
457
- case AtomicExpr::AO__c11_atomic_fetch_min:
458
532
case AtomicExpr::AO__hip_atomic_fetch_min:
459
533
case AtomicExpr::AO__opencl_atomic_fetch_min:
460
- case AtomicExpr::AO__atomic_fetch_min:
461
534
case AtomicExpr::AO__scoped_atomic_fetch_min:
462
535
463
- case AtomicExpr::AO__atomic_max_fetch:
464
536
case AtomicExpr::AO__scoped_atomic_max_fetch:
465
537
466
- case AtomicExpr::AO__c11_atomic_fetch_max:
467
538
case AtomicExpr::AO__hip_atomic_fetch_max:
468
539
case AtomicExpr::AO__opencl_atomic_fetch_max:
469
- case AtomicExpr::AO__atomic_fetch_max:
470
540
case AtomicExpr::AO__scoped_atomic_fetch_max:
471
541
472
- case AtomicExpr::AO__atomic_and_fetch:
473
542
case AtomicExpr::AO__scoped_atomic_and_fetch:
474
543
475
- case AtomicExpr::AO__c11_atomic_fetch_and:
476
544
case AtomicExpr::AO__hip_atomic_fetch_and:
477
545
case AtomicExpr::AO__opencl_atomic_fetch_and:
478
- case AtomicExpr::AO__atomic_fetch_and:
479
546
case AtomicExpr::AO__scoped_atomic_fetch_and:
480
547
481
- case AtomicExpr::AO__atomic_or_fetch:
482
548
case AtomicExpr::AO__scoped_atomic_or_fetch:
483
549
484
- case AtomicExpr::AO__c11_atomic_fetch_or:
485
550
case AtomicExpr::AO__hip_atomic_fetch_or:
486
551
case AtomicExpr::AO__opencl_atomic_fetch_or:
487
- case AtomicExpr::AO__atomic_fetch_or:
488
552
case AtomicExpr::AO__scoped_atomic_fetch_or:
489
553
490
- case AtomicExpr::AO__atomic_xor_fetch:
491
554
case AtomicExpr::AO__scoped_atomic_xor_fetch:
492
555
493
- case AtomicExpr::AO__c11_atomic_fetch_xor:
494
556
case AtomicExpr::AO__hip_atomic_fetch_xor:
495
557
case AtomicExpr::AO__opencl_atomic_fetch_xor:
496
- case AtomicExpr::AO__atomic_fetch_xor:
497
558
case AtomicExpr::AO__scoped_atomic_fetch_xor:
498
559
499
- case AtomicExpr::AO__atomic_nand_fetch:
500
560
case AtomicExpr::AO__scoped_atomic_nand_fetch:
501
561
502
- case AtomicExpr::AO__c11_atomic_fetch_nand:
503
- case AtomicExpr::AO__atomic_fetch_nand:
504
562
case AtomicExpr::AO__scoped_atomic_fetch_nand:
505
563
506
564
case AtomicExpr::AO__atomic_test_and_set:
@@ -518,9 +576,13 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
518
576
mlir::Operation *rmwOp = builder.create (loc, builder.getStringAttr (opName),
519
577
atomicOperands, atomicResTys);
520
578
579
+ if (fetchAttr)
580
+ rmwOp->setAttr (" binop" , fetchAttr);
521
581
rmwOp->setAttr (" mem_order" , orderAttr);
522
582
if (expr->isVolatile ())
523
583
rmwOp->setAttr (" is_volatile" , builder.getUnitAttr ());
584
+ if (fetchFirst && opName == cir::AtomicFetchOp::getOperationName ())
585
+ rmwOp->setAttr (" fetch_first" , builder.getUnitAttr ());
524
586
525
587
mlir::Value result = rmwOp->getResult (0 );
526
588
builder.createStore (loc, result, dest);
@@ -614,8 +676,41 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
614
676
isWeakExpr = e->getWeak ();
615
677
break ;
616
678
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:
617
708
case AtomicExpr::AO__atomic_exchange_n:
618
709
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:
619
714
case AtomicExpr::AO__c11_atomic_exchange:
620
715
case AtomicExpr::AO__c11_atomic_store:
621
716
val1 = emitValToTemp (*this , e->getVal1 ());
0 commit comments