diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index ae76246a9204..c6d1ff24f1d6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2119,7 +2119,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__sync_swap_4: case Builtin::BI__sync_swap_8: case Builtin::BI__sync_swap_16: - llvm_unreachable("BI__sync_swap1 like NYI"); + return emitBinaryAtomic(*this, cir::AtomicFetchKind::Xchg, E); case Builtin::BI__sync_lock_test_and_set_1: case Builtin::BI__sync_lock_test_and_set_2: diff --git a/clang/test/CIR/CodeGen/atomic.cpp b/clang/test/CIR/CodeGen/atomic.cpp index dee20e6dd388..7970107ce881 100644 --- a/clang/test/CIR/CodeGen/atomic.cpp +++ b/clang/test/CIR/CodeGen/atomic.cpp @@ -1271,3 +1271,99 @@ void lock_test_and_set(unsigned short* a, short b) { void lock_test_and_set(unsigned char* a, char b) { unsigned char c = __sync_lock_test_and_set(a, b); } + +// CHECK-LABEL: @_Z4swapPii +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !s32i, seq_cst) fetch_first : !s32i + +// LLVM-LABEL: @_Z4swapPii +// LLVM: atomicrmw xchg ptr {{.*}}, i32 {{.*}} seq_cst, align 4 + +// OGCG-LABEL: @_Z4swapPii +// OGCG: atomicrmw xchg ptr {{.*}}, i32 {{.*}} seq_cst, align 4 +void swap(int* a, int b) { + int c = __sync_swap(a, b); +} + +// CHECK-LABEL: @_Z4swapPll +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !s64i, seq_cst) fetch_first : !s64i + +// LLVM-LABEL: @_Z4swapPll +// LLVM: atomicrmw xchg ptr {{.*}}, i64 {{.*}} seq_cst, align 8 + +// OGCG-LABEL: @_Z4swapPll +// OGCG: atomicrmw xchg ptr {{.*}}, i64 {{.*}} seq_cst, align 8 +void swap(long* a, long b) { + long c = __sync_swap(a, b); +} + +// CHECK-LABEL: @_Z4swapPss +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !s16i, seq_cst) fetch_first : !s16i + +// LLVM-LABEL: @_Z4swapPss +// LLVM: atomicrmw xchg ptr {{.*}}, i16 {{.*}} seq_cst, align 2 + +// OGCG-LABEL: @_Z4swapPss +// OGCG: atomicrmw xchg ptr {{.*}}, i16 {{.*}} seq_cst, align 2 +void swap(short* a, short b) { + short c = __sync_swap(a, 2); +} + +// CHECK-LABEL: @_Z4swapPcc +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !s8i, seq_cst) fetch_first : !s8i + +// LLVM-LABEL: @_Z4swapPcc +// LLVM: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1 + +// OGCG-LABEL: @_Z4swapPcc +// OGCG: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1 +void swap(char* a, char b) { + char c = __sync_swap(a, b); +} + +// CHECK-LABEL: @_Z4swapPji +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !u32i, seq_cst) fetch_first : !u32i + +// LLVM-LABEL: @_Z4swapPji +// LLVM: atomicrmw xchg ptr {{.*}}, i32 {{.*}} seq_cst, align 4 + +// OGCG-LABEL: @_Z4swapPji +// OGCG: atomicrmw xchg ptr {{.*}}, i32 {{.*}} seq_cst, align 4 +void swap(unsigned int* a, int b) { + unsigned int c = __sync_swap(a, b); +} + +// CHECK-LABEL: @_Z4swapPml +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !u64i, seq_cst) fetch_first : !u64i + +// LLVM-LABEL: @_Z4swapPml +// LLVM: atomicrmw xchg ptr {{.*}}, i64 {{.*}} seq_cst, align 8 + +// OGCG-LABEL: @_Z4swapPml +// OGCG: atomicrmw xchg ptr {{.*}}, i64 {{.*}} seq_cst, align 8 +void swap(unsigned long* a, long b) { + unsigned long c = __sync_swap(a, b); +} + +// CHECK-LABEL: @_Z4swapPts +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !u16i, seq_cst) fetch_first : !u16i +// +// LLVM-LABEL: @_Z4swapPts +// LLVM: atomicrmw xchg ptr {{.*}}, i16 {{.*}} seq_cst, align 2 + +// OGCG-LABEL: @_Z4swapPts +// OGCG: atomicrmw xchg ptr {{.*}}, i16 {{.*}} seq_cst, align 2 +void swap(unsigned short* a, short b) { + unsigned long long c = __sync_swap(a, b); +} + +// CHECK-LABEL: @_Z4swapPhc +// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr, {{.*}} : !u8i, seq_cst) fetch_first : !u8i + +// LLVM-LABEL: @_Z4swapPhc +// LLVM: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1 + +// OGCG-LABEL: @_Z4swapPhc +// OGCG: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1 +void swap(unsigned char* a, char b) { + unsigned char c = __sync_swap(a, b); +}