Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -5934,7 +5934,8 @@ def CIR_AtomicFetchKind : CIR_I32EnumAttr<
I32EnumAttrCase<"Or", 4, "or">,
I32EnumAttrCase<"Nand", 5, "nand">,
I32EnumAttrCase<"Max", 6, "max">,
I32EnumAttrCase<"Min", 7, "min">
I32EnumAttrCase<"Min", 7, "min">,
I32EnumAttrCase<"Xchg", 8, "xchg">
]>;

def CIR_AtomicFetch : CIR_Op<"atomic.fetch", [
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__sync_lock_test_and_set_4:
case Builtin::BI__sync_lock_test_and_set_8:
case Builtin::BI__sync_lock_test_and_set_16:
llvm_unreachable("BI__sync_lock_test_and_set_1 like NYI");
return emitBinaryAtomic(*this, cir::AtomicFetchKind::Xchg, E);

case Builtin::BI__sync_lock_release_1:
case Builtin::BI__sync_lock_release_2:
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3602,6 +3602,8 @@ mlir::LLVM::AtomicBinOp CIRToLLVMAtomicFetchLowering::getLLVMAtomicBinOp(
return isSignedInt ? mlir::LLVM::AtomicBinOp::min
: mlir::LLVM::AtomicBinOp::umin;
}
case cir::AtomicFetchKind::Xchg:
return mlir::LLVM::AtomicBinOp::xchg;
}
llvm_unreachable("Unknown atomic fetch opcode");
}
Expand Down
75 changes: 75 additions & 0 deletions clang/test/CIR/CodeGen/atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1196,3 +1196,78 @@ void clear(void *p, volatile void *vp) {

// LLVM: store atomic volatile i8 0, ptr %{{.+}} seq_cst, align 1
}

// CHECK-LABEL: @_Z17lock_test_and_setPii
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!s32i>, {{.*}} : !s32i, seq_cst) fetch_first : !s32i

// LLVM-LABEL: @_Z17lock_test_and_setPii
// LLVM: atomicrmw xchg ptr {{.*}}, i32 {{.*}} seq_cst, align 4
void lock_test_and_set(int* a, int b) {
int c = __sync_lock_test_and_set(a, b);
}


// CHECK-LABEL: @_Z17lock_test_and_setPll
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!s64i>, {{.*}} : !s64i, seq_cst) fetch_first : !s64i

// LLVM-LABEL: @_Z17lock_test_and_setPll
// LLVM: atomicrmw xchg ptr {{.*}}, i64 {{.*}} seq_cst, align 8
void lock_test_and_set(long* a, long b) {
long c = __sync_lock_test_and_set(a, b);
}

// CHECK-LABEL: @_Z17lock_test_and_setPss
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!s16i>, {{.*}} : !s16i, seq_cst) fetch_first : !s16i

// LLVM-LABEL: @_Z17lock_test_and_setPss
// LLVM: atomicrmw xchg ptr {{.*}}, i16 {{.*}} seq_cst, align 2
void lock_test_and_set(short* a, short b) {
short c = __sync_lock_test_and_set(a, 2);
}


// CHECK-LABEL: @_Z17lock_test_and_setPcc
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!s8i>, {{.*}} : !s8i, seq_cst) fetch_first : !s8i

// LLVM-LABEL: @_Z17lock_test_and_setPcc
// LLVM: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1
void lock_test_and_set(char* a, char b) {
char c = __sync_lock_test_and_set(a, b);
}

// CHECK-LABEL: @_Z17lock_test_and_setPji
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!u32i>, {{.*}} : !u32i, seq_cst) fetch_first : !u32i

// LLVM-LABEL: @_Z17lock_test_and_setPji
// LLVM: atomicrmw xchg ptr {{.*}}, i32 {{.*}} seq_cst, align 4
void lock_test_and_set(unsigned int* a, int b) {
unsigned int c = __sync_lock_test_and_set(a, b);
}


// CHECK-LABEL: @_Z17lock_test_and_setPml
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!u64i>, {{.*}} : !u64i, seq_cst) fetch_first : !u64i

// LLVM-LABEL: @_Z17lock_test_and_setPml
// LLVM: atomicrmw xchg ptr {{.*}}, i64 {{.*}} seq_cst, align 8
void lock_test_and_set(unsigned long* a, long b) {
unsigned long c = __sync_lock_test_and_set(a, b);
}

// CHECK-LABEL: @_Z17lock_test_and_setPts
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!u16i>, {{.*}} : !u16i, seq_cst) fetch_first : !u16i
//
// LLVM-LABEL: @_Z17lock_test_and_setPts
// LLVM: atomicrmw xchg ptr {{.*}}, i16 {{.*}} seq_cst, align 2
void lock_test_and_set(unsigned short* a, short b) {
unsigned long long c = __sync_lock_test_and_set(a, b);
}

// CHECK-LABEL: @_Z17lock_test_and_setPhc
// CHECK: cir.atomic.fetch(xchg, {{.*}} : !cir.ptr<!u8i>, {{.*}} : !u8i, seq_cst) fetch_first : !u8i

// LLVM-LABEL: @_Z17lock_test_and_setPhc
// LLVM: atomicrmw xchg ptr {{.*}}, i8 {{.*}} seq_cst, align 1
void lock_test_and_set(unsigned char* a, char b) {
unsigned char c = __sync_lock_test_and_set(a, b);
}
Loading