Skip to content

Commit

Permalink
[CIR][CirGen][Bugfix] Fixes __sync_fetch_and_add for unsigned integers (
Browse files Browse the repository at this point in the history
llvm#799)

`__sync_fetch_and_add` currently doesn't support unsigned integers. 

The following code snippet, for example, raises an error:  
```
#include <stdint.h>

void foo(uint64_t x) {
  __sync_fetch_and_add(&x, 1);
}
```
The error can be traced down to this line `auto intType =
builder.getSIntNTy(cgf.getContext().getTypeSize(typ));` from
`clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp`.
  • Loading branch information
bruteforceboy authored and lanza committed Oct 12, 2024
1 parent 2f86e11 commit 403f4dc
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
5 changes: 4 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ makeBinaryAtomicValue(CIRGenFunction &cgf, mlir::cir::AtomicFetchKind kind,

Address destAddr = checkAtomicAlignment(cgf, expr);
auto &builder = cgf.getBuilder();
auto intType = builder.getSIntNTy(cgf.getContext().getTypeSize(typ));
auto intType =
expr->getArg(0)->getType()->getPointeeType()->isUnsignedIntegerType()
? builder.getUIntNTy(cgf.getContext().getTypeSize(typ))
: builder.getSIntNTy(cgf.getContext().getTypeSize(typ));
mlir::Value val = cgf.buildScalarExpr(expr->getArg(1));
mlir::Type valueType = val.getType();
val = buildToInt(cgf, val, typ, intType);
Expand Down
27 changes: 27 additions & 0 deletions clang/test/CIR/CodeGen/atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,3 +471,30 @@ void cmp_val_short(short* p, short x, short u) {
void cmp_val_byte(char* p, char x, char u) {
char r = __sync_val_compare_and_swap(p, x, u);
}

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

// LLVM-LABEL: @_Z8inc_uint
// LLVM: atomicrmw add ptr {{.*}}, i32 {{.*}} seq_cst, align 4
void inc_uint(unsigned int* a, int b) {
unsigned int c = __sync_fetch_and_add(a, b);
}

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

// LLVM-LABEL: @_Z9inc_ulong
// LLVM: atomicrmw add ptr {{.*}}, i64 {{.*}} seq_cst, align 8
void inc_ulong(unsigned long* a, long b) {
unsigned long c = __sync_fetch_and_add(a, b);
}

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

// LLVM-LABEL: @_Z9inc_uchar
// LLVM: atomicrmw add ptr {{.*}}, i8 {{.*}} seq_cst, align 1
void inc_uchar(unsigned char* a, char b) {
unsigned char c = __sync_fetch_and_add(a, b);
}
2 changes: 1 addition & 1 deletion clang/test/CodeGen/atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,4 @@ void force_global_uses(void) {
// X86: call void @__atomic_load(i32 noundef 16, ptr noundef @glob_longdbl, ptr noundef %atomic-temp
// X86-NEXT: %0 = load x86_fp80, ptr %atomic-temp, align 16
// SYSTEMZ: load atomic fp128, ptr @[[GLOB_LONGDBL]] seq_cst
}
}

0 comments on commit 403f4dc

Please sign in to comment.