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
