Author: Ayokunle Amodu
Date: 2026-03-12T20:12:41-06:00
New Revision: 48f4d31f6a3b76aff1f0cf89c90610762db840bd

URL: 
https://github.com/llvm/llvm-project/commit/48f4d31f6a3b76aff1f0cf89c90610762db840bd
DIFF: 
https://github.com/llvm/llvm-project/commit/48f4d31f6a3b76aff1f0cf89c90610762db840bd.diff

LOG: [CIR][CIRGen] Add support for __sync_* binary atomic builtins (#186026)

Adds CIRGen support for a subset of the __sync_fetch_and_* builtins,
including arithmetic (add, sub) and bitwise (and, or, xor, nand)
variants.

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
    clang/test/CIR/CodeGen/atomic.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index e9a8768e8213f..5d9ddbe5c3f22 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -116,7 +116,8 @@ static Address checkAtomicAlignment(CIRGenFunction &cgf, 
const CallExpr *e) {
 /// and the expression node.
 static mlir::Value makeBinaryAtomicValue(
     CIRGenFunction &cgf, cir::AtomicFetchKind kind, const CallExpr *expr,
-    mlir::Type *originalArgType, mlir::Value *emittedArgValue = nullptr,
+    mlir::Type *originalArgType = nullptr,
+    mlir::Value *emittedArgValue = nullptr,
     cir::MemOrder ordering = cir::MemOrder::SequentiallyConsistent) {
 
   QualType type = expr->getType();
@@ -159,6 +160,8 @@ static mlir::Value makeBinaryAtomicValue(
   // memory location and returns the old value.
   if (emittedArgValue) {
     *emittedArgValue = val;
+    assert(originalArgType != nullptr &&
+           "originalArgType must be provided when emittedArgValue is set");
     *originalArgType = valueType;
   }
 
@@ -169,6 +172,12 @@ static mlir::Value makeBinaryAtomicValue(
   return rmwi->getResult(0);
 }
 
+static RValue emitBinaryAtomic(CIRGenFunction &cgf,
+                               cir::AtomicFetchKind atomicOpkind,
+                               const CallExpr *e) {
+  return RValue::get(makeBinaryAtomicValue(cgf, atomicOpkind, e));
+}
+
 template <typename BinOp>
 static RValue emitBinaryAtomicPost(CIRGenFunction &cgf,
                                    cir::AtomicFetchKind atomicOpkind,
@@ -1720,36 +1729,43 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl 
&gd, unsigned builtinID,
   case Builtin::BI__sync_lock_test_and_set:
   case Builtin::BI__sync_lock_release:
   case Builtin::BI__sync_swap:
+    return errorBuiltinNYI(*this, e, builtinID);
   case Builtin::BI__sync_fetch_and_add_1:
   case Builtin::BI__sync_fetch_and_add_2:
   case Builtin::BI__sync_fetch_and_add_4:
   case Builtin::BI__sync_fetch_and_add_8:
   case Builtin::BI__sync_fetch_and_add_16:
+    return emitBinaryAtomic(*this, cir::AtomicFetchKind::Add, e);
   case Builtin::BI__sync_fetch_and_sub_1:
   case Builtin::BI__sync_fetch_and_sub_2:
   case Builtin::BI__sync_fetch_and_sub_4:
   case Builtin::BI__sync_fetch_and_sub_8:
   case Builtin::BI__sync_fetch_and_sub_16:
+    return emitBinaryAtomic(*this, cir::AtomicFetchKind::Sub, e);
   case Builtin::BI__sync_fetch_and_or_1:
   case Builtin::BI__sync_fetch_and_or_2:
   case Builtin::BI__sync_fetch_and_or_4:
   case Builtin::BI__sync_fetch_and_or_8:
   case Builtin::BI__sync_fetch_and_or_16:
+    return emitBinaryAtomic(*this, cir::AtomicFetchKind::Or, e);
   case Builtin::BI__sync_fetch_and_and_1:
   case Builtin::BI__sync_fetch_and_and_2:
   case Builtin::BI__sync_fetch_and_and_4:
   case Builtin::BI__sync_fetch_and_and_8:
   case Builtin::BI__sync_fetch_and_and_16:
+    return emitBinaryAtomic(*this, cir::AtomicFetchKind::And, e);
   case Builtin::BI__sync_fetch_and_xor_1:
   case Builtin::BI__sync_fetch_and_xor_2:
   case Builtin::BI__sync_fetch_and_xor_4:
   case Builtin::BI__sync_fetch_and_xor_8:
   case Builtin::BI__sync_fetch_and_xor_16:
+    return emitBinaryAtomic(*this, cir::AtomicFetchKind::Xor, e);
   case Builtin::BI__sync_fetch_and_nand_1:
   case Builtin::BI__sync_fetch_and_nand_2:
   case Builtin::BI__sync_fetch_and_nand_4:
   case Builtin::BI__sync_fetch_and_nand_8:
   case Builtin::BI__sync_fetch_and_nand_16:
+    return emitBinaryAtomic(*this, cir::AtomicFetchKind::Nand, e);
   case Builtin::BI__sync_fetch_and_min:
   case Builtin::BI__sync_fetch_and_max:
   case Builtin::BI__sync_fetch_and_umin:

diff  --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c
index 9bce73f253a11..200ebc549ef2b 100644
--- a/clang/test/CIR/CodeGen/atomic.c
+++ b/clang/test/CIR/CodeGen/atomic.c
@@ -1416,8 +1416,528 @@ int c11_atomic_fetch_nand(_Atomic(int) *ptr, int value) 
{
   // OGCG:      %[[RES:.+]] = atomicrmw nand ptr %{{.+}}, i32 %{{.+}} seq_cst, 
align 4
   // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4
 }
+void inc_int(int* a, int b) {
+  // CIR-LABEL: @inc_int
+  // CIR: %[[PTR:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CIR: %[[VAL:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!s32i>, !s32i
+  // CIR: %[[RES:.*]] = cir.atomic.fetch add seq_cst syncscope(system) 
fetch_first %[[PTR]], %[[VAL]] : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: cir.store {{.*}} %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
+
+  // LLVM-LABEL: @inc_int
+  // LLVM: atomicrmw add ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @inc_int
+  // OGCG: atomicrmw add ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  int c = __sync_fetch_and_add(a, b);
+}
+
+void inc_long(long* a, long b) {
+  // CIR-LABEL: @inc_long
+  // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s64i>, !s64i) -> !s64i
+
+  // LLVM-LABEL: @inc_long
+  // LLVM: atomicrmw add ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @inc_long
+  // OGCG: atomicrmw add ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  long c = __sync_fetch_and_add(a, 2);
+}
+
+void inc_short(short* a, short b) {
+  // CIR-LABEL: @inc_short
+  // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s16i>, !s16i) -> !s16i
+
+  // LLVM-LABEL: @inc_short
+  // LLVM: atomicrmw add ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+
+  // OGCG-LABEL: @inc_short
+  // OGCG: atomicrmw add ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+  short c = __sync_fetch_and_add(a, 2);
+}
+
+void inc_byte(char* a, char b) {
+  // CIR-LABEL: @inc_byte
+  // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s8i>, !s8i) -> !s8i
+
+  // LLVM-LABEL: @inc_byte
+  // LLVM: atomicrmw add ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @inc_byte
+  // OGCG: atomicrmw add ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  char c = __sync_fetch_and_add(a, b);
+}
+
+void inc_uint(unsigned int* a, int b) {
+  // CIR-LABEL: @inc_uint
+  // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u32i>, !u32i) -> !u32i
+
+  // LLVM-LABEL: @inc_uint
+  // LLVM: atomicrmw add ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @inc_uint
+  // OGCG: atomicrmw add ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  unsigned int c = __sync_fetch_and_add(a, b);
+}
+
+void inc_ulong(unsigned long* a, long b) {
+  // CIR-LABEL: @inc_ulong
+  // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u64i>, !u64i) -> !u64i
+
+  // LLVM-LABEL: @inc_ulong
+  // LLVM: atomicrmw add ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @inc_ulong
+  // OGCG: atomicrmw add ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  unsigned long c = __sync_fetch_and_add(a, b);
+}
+
+void inc_uchar(unsigned char* a, char b) {
+  // CIR-LABEL: @inc_uchar
+  // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u8i>, !u8i) -> !u8i
+
+  // LLVM-LABEL: @inc_uchar
+  // LLVM: atomicrmw add ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @inc_uchar
+  // OGCG: atomicrmw add ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  unsigned char c = __sync_fetch_and_add(a, b);
+}
+
+void sub_int(int* a, int b) {
+  // CIR-LABEL: @sub_int
+  // CIR: %[[PTR:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CIR: %[[VAL:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!s32i>, !s32i
+  // CIR: %[[RES:.*]] = cir.atomic.fetch sub seq_cst syncscope(system) 
fetch_first %[[PTR]], %[[VAL]] : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: cir.store {{.*}} %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
+
+  // LLVM-LABEL: @sub_int
+  // LLVM: atomicrmw sub ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @sub_int
+  // OGCG: atomicrmw sub ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  int c = __sync_fetch_and_sub(a, b);
+}
+
+void sub_long(long* a, long b) {
+  // CIR-LABEL: @sub_long
+  // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s64i>, !s64i) -> !s64i
+
+  // LLVM-LABEL: @sub_long
+  // LLVM: atomicrmw sub ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @sub_long
+  // OGCG: atomicrmw sub ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  long c = __sync_fetch_and_sub(a, 2);
+}
+
+void sub_short(short* a, short b) {
+  // CIR-LABEL: @sub_short
+  // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s16i>, !s16i) -> !s16i
+
+  // LLVM-LABEL: @sub_short
+  // LLVM: atomicrmw sub ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+
+  // OGCG-LABEL: @sub_short
+  // OGCG: atomicrmw sub ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+  short c = __sync_fetch_and_sub(a, 2);
+}
+
+void sub_byte(char* a, char b) {
+  // CIR-LABEL: @sub_byte
+  // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s8i>, !s8i) -> !s8i
+
+  // LLVM-LABEL: @sub_byte
+  // LLVM: atomicrmw sub ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @sub_byte
+  // OGCG: atomicrmw sub ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  char c = __sync_fetch_and_sub(a, b);
+}
+
+void sub_uint(unsigned int* a, int b) {
+  // CIR-LABEL: @sub_uint
+  // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u32i>, !u32i) -> !u32i
+
+  // LLVM-LABEL: @sub_uint
+  // LLVM: atomicrmw sub ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @sub_uint
+  // OGCG: atomicrmw sub ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  unsigned int c = __sync_fetch_and_sub(a, b);
+}
+
+void sub_ulong(unsigned long* a, long b) {
+  // CIR-LABEL: @sub_ulong
+  // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u64i>, !u64i) -> !u64i
+
+  // LLVM-LABEL: @sub_ulong
+  // LLVM: atomicrmw sub ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @sub_ulong
+  // OGCG: atomicrmw sub ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  unsigned long c = __sync_fetch_and_sub(a, b);
+}
+
+void sub_uchar(unsigned char* a, char b) {
+  // CIR-LABEL: @sub_uchar
+  // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u8i>, !u8i) -> !u8i
+
+  // LLVM-LABEL: @sub_uchar
+  // LLVM: atomicrmw sub ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @sub_uchar
+  // OGCG: atomicrmw sub ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  unsigned char c = __sync_fetch_and_sub(a, b);
+}
+
+void or_int(int* a, int b) {
+  // CIR-LABEL: or_int
+  // CIR: %[[PTR:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CIR: %[[VAL:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!s32i>, !s32i
+  // CIR: %[[RES:.*]] = cir.atomic.fetch or seq_cst syncscope(system) 
fetch_first %[[PTR]], %[[VAL]] : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: cir.store {{.*}} %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
+
+  // LLVM-LABEL: or_int
+  // LLVM: atomicrmw or ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: or_int
+  // OGCG: atomicrmw or ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  int c = __sync_fetch_and_or(a, b);
+}
+
+void or_long(long* a, long b) {
+  // CIR-LABEL: @or_long
+  // CIR: cir.atomic.fetch or seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s64i>, !s64i) -> !s64i
+
+  // LLVM-LABEL: @or_long
+  // LLVM: atomicrmw or ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @or_long
+  // OGCG: atomicrmw or ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  long c = __sync_fetch_and_or(a, 2);
+}
+
+void or_short(short* a, short b) {
+  // CIR-LABEL: @or_short
+  // CIR: cir.atomic.fetch or seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s16i>, !s16i) -> !s16i
+
+  // LLVM-LABEL: @or_short
+  // LLVM: atomicrmw or ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+
+  // OGCG-LABEL: @or_short
+  // OGCG: atomicrmw or ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+  short c = __sync_fetch_and_or(a, 2);
+}
+
+void or_byte(char* a, char b) {
+  // CIR-LABEL: @or_byte
+  // CIR: cir.atomic.fetch or seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s8i>, !s8i) -> !s8i
+
+  // LLVM-LABEL: @or_byte
+  // LLVM: atomicrmw or ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @or_byte
+  // OGCG: atomicrmw or ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  char c = __sync_fetch_and_or(a, b);
+}
+
+void or_uint(unsigned int* a, int b) {
+  // CIR-LABEL: @or_uint
+  // CIR: cir.atomic.fetch or seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u32i>, !u32i) -> !u32i
+
+  // LLVM-LABEL: @or_uint
+  // LLVM: atomicrmw or ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @or_uint
+  // OGCG: atomicrmw or ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  unsigned int c = __sync_fetch_and_or(a, b);
+}
+
+void or_ulong(unsigned long* a, long b) {
+  // CIR-LABEL: @or_ulong
+  // CIR: cir.atomic.fetch or seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u64i>, !u64i) -> !u64i
+
+  // LLVM-LABEL: @or_ulong
+  // LLVM: atomicrmw or ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @or_ulong
+  // OGCG: atomicrmw or ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  unsigned long c = __sync_fetch_and_or(a, b);
+}
+
+void or_uchar(unsigned char* a, char b) {
+  // CIR-LABEL: @or_uchar
+  // CIR: cir.atomic.fetch or seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u8i>, !u8i) -> !u8i
+
+  // LLVM-LABEL: @or_uchar
+  // LLVM: atomicrmw or ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @or_uchar
+  // OGCG: atomicrmw or ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  unsigned char c = __sync_fetch_and_or(a, b);
+}
+
+void xor_int(int* a, int b) {
+  // CIR-LABEL: xor_int
+  // CIR: %[[PTR:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CIR: %[[VAL:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!s32i>, !s32i
+  // CIR: %[[RES:.*]] = cir.atomic.fetch xor seq_cst syncscope(system) 
fetch_first %[[PTR]], %[[VAL]] : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: cir.store {{.*}} %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
 
-// CHECK-LABEL: @test_op_and_fetch
+  // LLVM-LABEL: xor_int
+  // LLVM: atomicrmw xor ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: xor_int
+  // OGCG: atomicrmw xor ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  int c = __sync_fetch_and_xor(a, b);
+}
+
+void xor_long(long* a, long b) {
+  // CIR-LABEL: @xor_long
+  // CIR: cir.atomic.fetch xor seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s64i>, !s64i) -> !s64i
+
+  // LLVM-LABEL: @xor_long
+  // LLVM: atomicrmw xor ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @xor_long
+  // OGCG: atomicrmw xor ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  long c = __sync_fetch_and_xor(a, 2);
+}
+
+void xor_short(short* a, short b) {
+  // CIR-LABEL: @xor_short
+  // CIR: cir.atomic.fetch xor seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s16i>, !s16i) -> !s16i
+
+  // LLVM-LABEL: @xor_short
+  // LLVM: atomicrmw xor ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+
+  // OGCG-LABEL: @xor_short
+  // OGCG: atomicrmw xor ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+  short c = __sync_fetch_and_xor(a, 2);
+}
+
+void xor_byte(char* a, char b) {
+  // CIR-LABEL: @xor_byte
+  // CIR: cir.atomic.fetch xor seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s8i>, !s8i) -> !s8i
+
+  // LLVM-LABEL: @xor_byte
+  // LLVM: atomicrmw xor ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @xor_byte
+  // OGCG: atomicrmw xor ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  char c = __sync_fetch_and_xor(a, b);
+}
+
+void xor_uint(unsigned int* a, int b) {
+  // CIR-LABEL: @xor_uint
+  // CIR: cir.atomic.fetch xor seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u32i>, !u32i) -> !u32i
+
+  // LLVM-LABEL: @xor_uint
+  // LLVM: atomicrmw xor ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @xor_uint
+  // OGCG: atomicrmw xor ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  unsigned int c = __sync_fetch_and_xor(a, b);
+}
+
+void xor_ulong(unsigned long* a, long b) {
+  // CIR-LABEL: @xor_ulong
+  // CIR: cir.atomic.fetch xor seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u64i>, !u64i) -> !u64i
+
+  // LLVM-LABEL: @xor_ulong
+  // LLVM: atomicrmw xor ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @xor_ulong
+  // OGCG: atomicrmw xor ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  unsigned long c = __sync_fetch_and_xor(a, b);
+}
+
+void xor_uchar(unsigned char* a, char b) {
+  // CIR-LABEL: @xor_uchar
+  // CIR: cir.atomic.fetch xor seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u8i>, !u8i) -> !u8i
+
+  // LLVM-LABEL: @xor_uchar
+  // LLVM: atomicrmw xor ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @xor_uchar
+  // OGCG: atomicrmw xor ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  unsigned char c = __sync_fetch_and_xor(a, b);
+}
+void and_int(int* a, int b) {
+  // CIR-LABEL: and_int
+  // CIR: %[[PTR:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CIR: %[[VAL:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!s32i>, !s32i
+  // CIR: %[[RES:.*]] = cir.atomic.fetch and seq_cst syncscope(system) 
fetch_first %[[PTR]], %[[VAL]] : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: cir.store {{.*}} %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
+
+  // LLVM-LABEL: and_int
+  // LLVM: atomicrmw and ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: and_int
+  // OGCG: atomicrmw and ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  int c = __sync_fetch_and_and(a, b);
+}
+
+void and_long(long* a, long b) {
+  // CIR-LABEL: @and_long
+  // CIR: cir.atomic.fetch and seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s64i>, !s64i) -> !s64i
+
+  // LLVM-LABEL: @and_long
+  // LLVM: atomicrmw and ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @and_long
+  // OGCG: atomicrmw and ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  long c = __sync_fetch_and_and(a, 2);
+}
+
+void and_short(short* a, short b) {
+  // CIR-LABEL: @and_short
+  // CIR: cir.atomic.fetch and seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s16i>, !s16i) -> !s16i
+
+  // LLVM-LABEL: @and_short
+  // LLVM: atomicrmw and ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+
+  // OGCG-LABEL: @and_short
+  // OGCG: atomicrmw and ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+  short c = __sync_fetch_and_and(a, 2);
+}
+
+void and_byte(char* a, char b) {
+  // CIR-LABEL: @and_byte
+  // CIR: cir.atomic.fetch and seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s8i>, !s8i) -> !s8i
+
+  // LLVM-LABEL: @and_byte
+  // LLVM: atomicrmw and ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @and_byte
+  // OGCG: atomicrmw and ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  char c = __sync_fetch_and_and(a, b);
+}
+
+void and_uint(unsigned int* a, int b) {
+  // CIR-LABEL: @and_uint
+  // CIR: cir.atomic.fetch and seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u32i>, !u32i) -> !u32i
+
+  // LLVM-LABEL: @and_uint
+  // LLVM: atomicrmw and ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @and_uint
+  // OGCG: atomicrmw and ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  unsigned int c = __sync_fetch_and_and(a, b);
+}
+
+void and_ulong(unsigned long* a, long b) {
+  // CIR-LABEL: @and_ulong
+  // CIR: cir.atomic.fetch and seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u64i>, !u64i) -> !u64i
+
+  // LLVM-LABEL: @and_ulong
+  // LLVM: atomicrmw and ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @and_ulong
+  // OGCG: atomicrmw and ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  unsigned long c = __sync_fetch_and_and(a, b);
+}
+
+void and_uchar(unsigned char* a, char b) {
+  // CIR-LABEL: @and_uchar
+  // CIR: cir.atomic.fetch and seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u8i>, !u8i) -> !u8i
+
+  // LLVM-LABEL: @and_uchar
+  // LLVM: atomicrmw and ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @and_uchar
+  // OGCG: atomicrmw and ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  unsigned char c = __sync_fetch_and_and(a, b);
+}
+
+void nand_int(int* a, int b) {
+  // CIR-LABEL: nand_int
+  // CIR: %[[PTR:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.ptr<!s32i>>, 
!cir.ptr<!s32i>
+  // CIR: %[[VAL:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!s32i>, !s32i
+  // CIR: %[[RES:.*]] = cir.atomic.fetch nand seq_cst syncscope(system) 
fetch_first %[[PTR]], %[[VAL]] : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: cir.store {{.*}} %[[RES]], {{.*}} : !s32i, !cir.ptr<!s32i>
+
+  // LLVM-LABEL: nand_int
+  // LLVM: atomicrmw nand ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: nand_int
+  // OGCG: atomicrmw nand ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  int c = __sync_fetch_and_nand(a, b);
+}
+
+void nand_long(long* a, long b) {
+  // CIR-LABEL: @nand_long
+  // CIR: cir.atomic.fetch nand seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s64i>, !s64i) -> !s64i
+
+  // LLVM-LABEL: @nand_long
+  // LLVM: atomicrmw nand ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @nand_long
+  // OGCG: atomicrmw nand ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  long c = __sync_fetch_and_nand(a, 2);
+}
+
+void nand_short(short* a, short b) {
+  // CIR-LABEL: @nand_short
+  // CIR: cir.atomic.fetch nand seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s16i>, !s16i) -> !s16i
+
+  // LLVM-LABEL: @nand_short
+  // LLVM: atomicrmw nand ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+
+  // OGCG-LABEL: @nand_short
+  // OGCG: atomicrmw nand ptr {{.*}}, i16 {{.*}} seq_cst, align 2
+  short c = __sync_fetch_and_nand(a, 2);
+}
+
+void nand_byte(char* a, char b) {
+  // CIR-LABEL: @nand_byte
+  // CIR: cir.atomic.fetch nand seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!s8i>, !s8i) -> !s8i
+
+  // LLVM-LABEL: @nand_byte
+  // LLVM: atomicrmw nand ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @nand_byte
+  // OGCG: atomicrmw nand ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  char c = __sync_fetch_and_nand(a, b);
+}
+
+void nand_uint(unsigned int* a, int b) {
+  // CIR-LABEL: @nand_uint
+  // CIR: cir.atomic.fetch nand seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u32i>, !u32i) -> !u32i
+
+  // LLVM-LABEL: @nand_uint
+  // LLVM: atomicrmw nand ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+
+  // OGCG-LABEL: @nand_uint
+  // OGCG: atomicrmw nand ptr {{.*}}, i32 {{.*}} seq_cst, align 4
+  unsigned int c = __sync_fetch_and_nand(a, b);
+}
+
+void nand_ulong(unsigned long* a, long b) {
+  // CIR-LABEL: @nand_ulong
+  // CIR: cir.atomic.fetch nand seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u64i>, !u64i) -> !u64i
+
+  // LLVM-LABEL: @nand_ulong
+  // LLVM: atomicrmw nand ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+
+  // OGCG-LABEL: @nand_ulong
+  // OGCG: atomicrmw nand ptr {{.*}}, i64 {{.*}} seq_cst, align 8
+  unsigned long c = __sync_fetch_and_nand(a, b);
+}
+
+void nand_uchar(unsigned char* a, char b) {
+  // CIR-LABEL: @nand_uchar
+  // CIR: cir.atomic.fetch nand seq_cst syncscope(system) fetch_first {{.*}}, 
{{.*}} : (!cir.ptr<!u8i>, !u8i) -> !u8i
+
+  // LLVM-LABEL: @nand_uchar
+  // LLVM: atomicrmw nand ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+
+  // OGCG-LABEL: @nand_uchar
+  // OGCG: atomicrmw nand ptr {{.*}}, i8 {{.*}} seq_cst, align 1
+  unsigned char c = __sync_fetch_and_nand(a, b);
+}
+
+// CIR-LABEL: @test_op_and_fetch
 // LLVM-LABEL: @test_op_and_fetch
 void test_op_and_fetch() {
   int *ptr;
@@ -2164,6 +2684,8 @@ void test_op_and_fetch() {
   ull = __sync_nand_and_fetch(&ull, uc);
 }
 
+
+
 int atomic_load_dynamic_order(int *ptr, int order) {
   // CIR-LABEL: atomic_load_dynamic_order
   // LLVM-LABEL: atomic_load_dynamic_order


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to