Skip to content

Commit fdb5606

Browse files
ghehglanza
authored andcommitted
[CIR][CIRGen][Builtin] Support unsigned type for _sync_(bool/val)_compare_and_swap (#955)
as title. Actually just follow the way in `makeBinaryAtomicValue` in the same file which did the right thing by creating SInt or UInt based on first argument's signess.
1 parent 2207992 commit fdb5606

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,10 @@ static mlir::Value MakeAtomicCmpXchgValue(CIRGenFunction &cgf,
269269
Address destAddr = checkAtomicAlignment(cgf, expr);
270270
auto &builder = cgf.getBuilder();
271271

272-
auto intType = builder.getSIntNTy(cgf.getContext().getTypeSize(typ));
272+
auto intType =
273+
expr->getArg(0)->getType()->getPointeeType()->isUnsignedIntegerType()
274+
? builder.getUIntNTy(cgf.getContext().getTypeSize(typ))
275+
: builder.getSIntNTy(cgf.getContext().getTypeSize(typ));
273276
auto cmpVal = cgf.buildScalarExpr(expr->getArg(1));
274277
cmpVal = buildToInt(cgf, cmpVal, typ, intType);
275278
auto newVal =

clang/test/CIR/CodeGen/atomic.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ void cmp_bool_int(int* p, int x, int u) {
442442
bool r = __sync_bool_compare_and_swap(p, x, u);
443443
}
444444

445+
445446
// CHECK-LABEL: @_Z13cmp_bool_long
446447
// CHECK: cir.atomic.cmp_xchg({{.*}} : !cir.ptr<!s64i>, {{.*}} : !s64i, {{.*}} : !s64i, success = seq_cst, failure = seq_cst) : (!s64i, !cir.bool)
447448

@@ -568,3 +569,83 @@ void inc_uchar(unsigned char* a, char b) {
568569
void sub_uchar(unsigned char* a, char b) {
569570
unsigned char c = __sync_fetch_and_sub(a, b);
570571
}
572+
573+
// CHECK-LABEL: @_Z13cmp_bool_uint
574+
// CHECK: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
575+
// CHECK: %[[CMP:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
576+
// CHECK: %[[CMP_U:.*]] = cir.cast(integral, %[[CMP]] : !s32i), !u32i
577+
// CHECK: %[[UPD:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
578+
// CHECK: %[[UPD_U:.*]] = cir.cast(integral, %[[UPD]] : !s32i), !u32i
579+
// CHECK: %[[OLD:.*]], %[[RES:.*]] = cir.atomic.cmp_xchg(%[[PTR]] : !cir.ptr<!u32i>, %[[CMP_U]] :
580+
// CHECK-SAME: !u32i, %[[UPD_U]] : !u32i, success = seq_cst, failure = seq_cst) : (!u32i, !cir.bool)
581+
// CHECK: cir.store %[[RES]], {{.*}} : !cir.bool, !cir.ptr<!cir.bool>
582+
583+
// LLVM-LABEL: @_Z13cmp_bool_uint
584+
// LLVM: %[[PTR:.*]] = load ptr
585+
// LLVM: %[[CMP:.*]] = load i32
586+
// LLVM: %[[UPD:.*]] = load i32
587+
// LLVM: %[[RES:.*]] = cmpxchg ptr %[[PTR]], i32 %[[CMP]], i32 %[[UPD]] seq_cst seq_cst
588+
// LLVM: %[[TMP:.*]] = extractvalue { i32, i1 } %[[RES]], 1
589+
// LLVM: %[[EXT:.*]] = zext i1 %[[TMP]] to i8
590+
// LLVM: store i8 %[[EXT]], ptr {{.*}}
591+
void cmp_bool_uint(unsigned int* p, int x, int u) {
592+
bool r = __sync_bool_compare_and_swap(p, x, u);
593+
}
594+
595+
// CHECK-LABEL: @_Z15cmp_bool_ushort
596+
// CHECK: cir.atomic.cmp_xchg({{.*}} : !cir.ptr<!u16i>, {{.*}} : !u16i, {{.*}} : !u16i, success = seq_cst, failure = seq_cst) : (!u16i, !cir.bool)
597+
598+
// LLVM-LABEL: @_Z15cmp_bool_ushort
599+
// LLVM: cmpxchg ptr {{.*}}, i16 {{.*}}, i16 {{.*}} seq_cst seq_cst
600+
void cmp_bool_ushort(unsigned short* p, short x, short u) {
601+
bool r = __sync_bool_compare_and_swap(p, x, u);
602+
}
603+
604+
// CHECK-LABEL: @_Z14cmp_bool_ulong
605+
// CHECK: cir.atomic.cmp_xchg({{.*}} : !cir.ptr<!u64i>, {{.*}} : !u64i, {{.*}} : !u64i, success = seq_cst, failure = seq_cst) : (!u64i, !cir.bool)
606+
607+
// LLVM-LABEL: @_Z14cmp_bool_ulong
608+
// LLVM: cmpxchg ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst
609+
void cmp_bool_ulong(unsigned long* p, long x, long u) {
610+
bool r = __sync_bool_compare_and_swap(p, x, u);
611+
}
612+
613+
// CHECK-LABEL: @_Z12cmp_val_uint
614+
// CHECK: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i>
615+
// CHECK: %[[CMP:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
616+
// CHECK: %[[CMP_U:.*]] = cir.cast(integral, %[[CMP]] : !s32i), !u32i
617+
// CHECK: %[[UPD:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
618+
// CHECK: %[[UPD_U:.*]] = cir.cast(integral, %[[UPD]] : !s32i), !u32i
619+
// CHECK: %[[OLD:.*]], %[[RES:.*]] = cir.atomic.cmp_xchg(%[[PTR]] : !cir.ptr<!u32i>, %[[CMP_U]] :
620+
// CHECK-SAME: !u32i, %[[UPD_U]] : !u32i, success = seq_cst, failure = seq_cst) : (!u32i, !cir.bool)
621+
// CHECK: %[[R:.*]] = cir.cast(integral, %[[OLD]] : !u32i), !s32i
622+
// CHECK: cir.store %[[R]], {{.*}} : !s32i, !cir.ptr<!s32i>
623+
624+
// LLVM-LABEL: @_Z12cmp_val_uint
625+
// LLVM: %[[PTR:.*]] = load ptr
626+
// LLVM: %[[CMP:.*]] = load i32
627+
// LLVM: %[[UPD:.*]] = load i32
628+
// LLVM: %[[RES:.*]] = cmpxchg ptr %[[PTR]], i32 %[[CMP]], i32 %[[UPD]] seq_cst seq_cst
629+
// LLVM: %[[TMP:.*]] = extractvalue { i32, i1 } %[[RES]], 0
630+
// LLVM: store i32 %[[TMP]], ptr {{.*}}
631+
void cmp_val_uint(unsigned int* p, int x, int u) {
632+
int r = __sync_val_compare_and_swap(p, x, u);
633+
}
634+
635+
// CHECK-LABEL: @_Z14cmp_val_ushort
636+
// CHECK: cir.atomic.cmp_xchg({{.*}} : !cir.ptr<!u16i>, {{.*}} : !u16i, {{.*}} : !u16i, success = seq_cst, failure = seq_cst) : (!u16i, !cir.bool)
637+
638+
// LLVM-LABEL: @_Z14cmp_val_ushort
639+
// LLVM: cmpxchg ptr {{.*}}, i16 {{.*}}, i16 {{.*}} seq_cst seq_cst
640+
void cmp_val_ushort(unsigned short* p, short x, short u) {
641+
short r = __sync_val_compare_and_swap(p, x, u);
642+
}
643+
644+
// CHECK-LABEL: @_Z13cmp_val_ulong
645+
// CHECK: cir.atomic.cmp_xchg({{.*}} : !cir.ptr<!u64i>, {{.*}} : !u64i, {{.*}} : !u64i, success = seq_cst, failure = seq_cst) : (!u64i, !cir.bool)
646+
647+
// LLVM-LABEL: @_Z13cmp_val_ulong
648+
// LLVM: cmpxchg ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst
649+
void cmp_val_ulong(unsigned long* p, long x, long u) {
650+
long r = __sync_val_compare_and_swap(p, x, u);
651+
}

0 commit comments

Comments
 (0)