https://github.com/dingcyrus updated https://github.com/llvm/llvm-project/pull/214606
>From 8b1f9aaf179275dd452687cf2a71218080e43766 Mon Sep 17 00:00:00 2001 From: Cyrus Ding <[email protected]> Date: Fri, 7 Aug 2026 09:53:16 +0800 Subject: [PATCH] [CIR] Implement missing __sync_* atomic builtins Add CIR codegen support for five legacy __sync_* builtins that previously emitted "Not Yet Implemented" errors: __sync_val_compare_and_swap -> cir.atomic.cmpxchg (seq_cst) __sync_bool_compare_and_swap -> cir.atomic.cmpxchg + cmp (seq_cst) __sync_swap -> cir.atomic.xchg (seq_cst) __sync_lock_test_and_set -> cir.atomic.xchg (acquire) __sync_lock_release -> cir.store 0 (release) Both unsuffixed and size-suffixed forms (_1, _2, _4, _8, _16) are handled, covering 30 builtin variants in total. The existing emitBinaryAtomic / emitBinaryAtomicPost infrastructure already handled the arithmetic __sync_* family (fetch_and_add, etc.). This patch adds the remaining compare-and-swap, exchange, and lock-release helpers: emitAtomicCmpXchgValue, emitAtomicCmpXchgBool, emitAtomicXchg, and emitAtomicLockRelease. Also fix a cosmetic issue in errorBuiltinNYI: the diagnostic hardcoded "X86" in the message even for target-independent builtins such as __sync_* compiled with --target=aarch64. Replace "unimplemented X86 builtin call" with "unimplemented builtin call". Fixes #214445. --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 78 +++++- .../test/CIR/CodeGenBuiltins/builtin-sync.cpp | 230 ++++++++++++++++++ .../CodeGenBuiltins/builtin-undef-rvalue.cpp | 2 +- 3 files changed, 302 insertions(+), 8 deletions(-) create mode 100644 clang/test/CIR/CodeGenBuiltins/builtin-sync.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index afb13572df5bf..ac919df426e8c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -247,6 +247,64 @@ static RValue emitBinaryAtomicPost(CIRGenFunction &cgf, return RValue::get(result); } +/// Emit a `cir.atomic.cmpxchg` for __sync_val_compare_and_swap_N and +/// __sync_bool_compare_and_swap_N. Returns the old value when `returnBool` is +/// false, otherwise returns a boolean success flag. +static RValue emitAtomicCmpXchg(CIRGenFunction &cgf, const CallExpr *e, + bool returnBool) { + Address destAddr = checkAtomicAlignment(cgf, e); + CIRGenBuilderTy &builder = cgf.getBuilder(); + mlir::Value destValue = destAddr.emitRawPointer(); + mlir::Value expected = cgf.emitScalarExpr(e->getArg(1)); + mlir::Value desired = cgf.emitScalarExpr(e->getArg(2)); + + auto cmpxchg = cir::AtomicCmpXchgOp::create( + builder, cgf.getLoc(e->getSourceRange()), destValue, expected, desired, + cir::MemOrder::SequentiallyConsistent, + cir::MemOrder::SequentiallyConsistent, cir::SyncScopeKind::System, + /*alignment=*/nullptr, /*weak=*/false, /*is_volatile=*/false); + + if (returnBool) { + // cir.atomic.cmpxchg already returns (old, success). Use the success flag + // directly instead of re-emitting the expected argument and comparing. + mlir::Value success = cmpxchg.getSuccess(); + mlir::Value result = + builder.createIntCast(success, cgf.convertType(e->getType())); + return RValue::get(result); + } + return RValue::get(cmpxchg.getOld()); +} + +/// Emit a `cir.atomic.xchg` for __sync_swap_N and __sync_lock_test_and_set_N. +static RValue emitAtomicXchg(CIRGenFunction &cgf, const CallExpr *e, + cir::MemOrder ordering) { + Address destAddr = checkAtomicAlignment(cgf, e); + CIRGenBuilderTy &builder = cgf.getBuilder(); + mlir::Value destValue = destAddr.emitRawPointer(); + mlir::Value val = cgf.emitScalarExpr(e->getArg(1)); + + auto xchg = cir::AtomicXchgOp::create( + builder, cgf.getLoc(e->getSourceRange()), destValue, val, ordering, + cir::SyncScopeKind::System, /*is_volatile=*/false); + return RValue::get(xchg.getResult()); +} + +/// Emit a release store of 0 for __sync_lock_release_N. +static void emitAtomicLockRelease(CIRGenFunction &cgf, const CallExpr *e) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + Address destAddr = checkAtomicAlignment(cgf, e); + mlir::Location loc = cgf.getLoc(e->getSourceRange()); + mlir::Type elemTy = destAddr.getElementType(); + mlir::Value zero = builder.getConstant(loc, builder.getZeroInitAttr(elemTy)); + auto orderAttr = + cir::MemOrderAttr::get(&cgf.getMLIRContext(), cir::MemOrder::Release); + auto scopeAttr = cir::SyncScopeKindAttr::get(&cgf.getMLIRContext(), + cir::SyncScopeKind::System); + builder.createStore(loc, zero, destAddr, /*isVolatile=*/false, + /*isNontemporal=*/false, + /*align=*/mlir::IntegerAttr{}, scopeAttr, orderAttr); +} + static void emitAtomicFenceOp(CIRGenFunction &cgf, const CallExpr *expr, cir::SyncScopeKind syncScope) { CIRGenBuilderTy &builder = cgf.getBuilder(); @@ -432,11 +490,11 @@ static RValue errorBuiltinNYI(CIRGenFunction &cgf, const CallExpr *e, if (cgf.getContext().BuiltinInfo.isLibFunction(builtinID)) { cgf.cgm.errorNYI( e->getSourceRange(), - std::string("unimplemented X86 library function builtin call: ") + + std::string("unimplemented library function builtin call: ") + cgf.getContext().BuiltinInfo.getName(builtinID)); } else { cgf.cgm.errorNYI(e->getSourceRange(), - std::string("unimplemented X86 builtin call: ") + + std::string("unimplemented builtin call: ") + cgf.getContext().BuiltinInfo.getName(builtinID)); } @@ -2052,7 +2110,7 @@ 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); + llvm_unreachable("Shouldn't make it through sema"); case Builtin::BI__sync_fetch_and_add_1: case Builtin::BI__sync_fetch_and_add_2: case Builtin::BI__sync_fetch_and_add_4: @@ -2140,26 +2198,32 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__sync_val_compare_and_swap_2: case Builtin::BI__sync_val_compare_and_swap_4: case Builtin::BI__sync_val_compare_and_swap_8: - case Builtin::BI__sync_val_compare_and_swap_16: + return emitAtomicCmpXchg(*this, e, /*returnBool=*/false); case Builtin::BI__sync_bool_compare_and_swap_1: case Builtin::BI__sync_bool_compare_and_swap_2: case Builtin::BI__sync_bool_compare_and_swap_4: case Builtin::BI__sync_bool_compare_and_swap_8: - case Builtin::BI__sync_bool_compare_and_swap_16: + return emitAtomicCmpXchg(*this, e, /*returnBool=*/true); case Builtin::BI__sync_swap_1: case Builtin::BI__sync_swap_2: case Builtin::BI__sync_swap_4: case Builtin::BI__sync_swap_8: - case Builtin::BI__sync_swap_16: + return emitAtomicXchg(*this, e, cir::MemOrder::SequentiallyConsistent); case Builtin::BI__sync_lock_test_and_set_1: case Builtin::BI__sync_lock_test_and_set_2: 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: + return emitAtomicXchg(*this, e, cir::MemOrder::SequentiallyConsistent); case Builtin::BI__sync_lock_release_1: case Builtin::BI__sync_lock_release_2: case Builtin::BI__sync_lock_release_4: case Builtin::BI__sync_lock_release_8: + emitAtomicLockRelease(*this, e); + return RValue::get(nullptr); + case Builtin::BI__sync_val_compare_and_swap_16: + case Builtin::BI__sync_bool_compare_and_swap_16: + case Builtin::BI__sync_swap_16: + case Builtin::BI__sync_lock_test_and_set_16: case Builtin::BI__sync_lock_release_16: return errorBuiltinNYI(*this, e, builtinID); case Builtin::BI__sync_synchronize: { diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-sync.cpp b/clang/test/CIR/CodeGenBuiltins/builtin-sync.cpp new file mode 100644 index 0000000000000..786f2cb9b6e96 --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/builtin-sync.cpp @@ -0,0 +1,230 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +extern "C" { + +// __sync_val_compare_and_swap + +// CIR-LABEL: @test_sync_val_compare_and_swap_1( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s8i>, !s8i, !s8i) -> (!s8i, !cir.bool) +// LLVM-LABEL: @test_sync_val_compare_and_swap_1( +// LLVM: cmpxchg ptr %{{.+}}, i8 %{{.+}}, i8 %{{.+}} seq_cst seq_cst, align 1 +// OGCG-LABEL: @test_sync_val_compare_and_swap_1( +// OGCG: cmpxchg ptr %{{.+}}, i8 %{{.+}}, i8 %{{.+}} seq_cst seq_cst, align 1 +char test_sync_val_compare_and_swap_1(char *p, char oldv, char newv) { + return __sync_val_compare_and_swap(p, oldv, newv); +} + +// CIR-LABEL: @test_sync_val_compare_and_swap_2( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s16i>, !s16i, !s16i) -> (!s16i, !cir.bool) +// LLVM-LABEL: @test_sync_val_compare_and_swap_2( +// LLVM: cmpxchg ptr %{{.+}}, i16 %{{.+}}, i16 %{{.+}} seq_cst seq_cst, align 2 +// OGCG-LABEL: @test_sync_val_compare_and_swap_2( +// OGCG: cmpxchg ptr %{{.+}}, i16 %{{.+}}, i16 %{{.+}} seq_cst seq_cst, align 2 +short test_sync_val_compare_and_swap_2(short *p, short oldv, short newv) { + return __sync_val_compare_and_swap(p, oldv, newv); +} + +// CIR-LABEL: @test_sync_val_compare_and_swap_4( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool) +// LLVM-LABEL: @test_sync_val_compare_and_swap_4( +// LLVM: cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst seq_cst, align 4 +// OGCG-LABEL: @test_sync_val_compare_and_swap_4( +// OGCG: cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst seq_cst, align 4 +int test_sync_val_compare_and_swap_4(int *p, int oldv, int newv) { + return __sync_val_compare_and_swap(p, oldv, newv); +} + +// CIR-LABEL: @test_sync_val_compare_and_swap_8( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s64i>, !s64i, !s64i) -> (!s64i, !cir.bool) +// LLVM-LABEL: @test_sync_val_compare_and_swap_8( +// LLVM: cmpxchg ptr %{{.+}}, i64 %{{.+}}, i64 %{{.+}} seq_cst seq_cst, align 8 +// OGCG-LABEL: @test_sync_val_compare_and_swap_8( +// OGCG: cmpxchg ptr %{{.+}}, i64 %{{.+}}, i64 %{{.+}} seq_cst seq_cst, align 8 +long long test_sync_val_compare_and_swap_8(long long *p, long long oldv, + long long newv) { + return __sync_val_compare_and_swap(p, oldv, newv); +} + +// __sync_bool_compare_and_swap + +// CIR-LABEL: @test_sync_bool_compare_and_swap_1( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s8i>, !s8i, !s8i) -> (!s8i, !cir.bool) +// LLVM-LABEL: @test_sync_bool_compare_and_swap_1( +// LLVM: cmpxchg ptr %{{.+}}, i8 %{{.+}}, i8 %{{.+}} seq_cst seq_cst, align 1 +// LLVM: extractvalue { i8, i1 } %{{.+}}, 1 +// OGCG-LABEL: @test_sync_bool_compare_and_swap_1( +// OGCG: cmpxchg ptr %{{.+}}, i8 %{{.+}}, i8 %{{.+}} seq_cst seq_cst, align 1 +// OGCG: extractvalue { i8, i1 } %{{.+}}, 1 +bool test_sync_bool_compare_and_swap_1(char *p, char oldv, char newv) { + return __sync_bool_compare_and_swap(p, oldv, newv); +} + +// CIR-LABEL: @test_sync_bool_compare_and_swap_2( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s16i>, !s16i, !s16i) -> (!s16i, !cir.bool) +// LLVM-LABEL: @test_sync_bool_compare_and_swap_2( +// LLVM: cmpxchg ptr %{{.+}}, i16 %{{.+}}, i16 %{{.+}} seq_cst seq_cst, align 2 +// LLVM: extractvalue { i16, i1 } %{{.+}}, 1 +// OGCG-LABEL: @test_sync_bool_compare_and_swap_2( +// OGCG: cmpxchg ptr %{{.+}}, i16 %{{.+}}, i16 %{{.+}} seq_cst seq_cst, align 2 +// OGCG: extractvalue { i16, i1 } %{{.+}}, 1 +bool test_sync_bool_compare_and_swap_2(short *p, short oldv, short newv) { + return __sync_bool_compare_and_swap(p, oldv, newv); +} + +// CIR-LABEL: @test_sync_bool_compare_and_swap_4( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i, !s32i) -> (!s32i, !cir.bool) +// LLVM-LABEL: @test_sync_bool_compare_and_swap_4( +// LLVM: cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst seq_cst, align 4 +// LLVM: extractvalue { i32, i1 } %{{.+}}, 1 +// OGCG-LABEL: @test_sync_bool_compare_and_swap_4( +// OGCG: cmpxchg ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst seq_cst, align 4 +// OGCG: extractvalue { i32, i1 } %{{.+}}, 1 +bool test_sync_bool_compare_and_swap_4(int *p, int oldv, int newv) { + return __sync_bool_compare_and_swap(p, oldv, newv); +} + +// CIR-LABEL: @test_sync_bool_compare_and_swap_8( +// CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %{{.+}}, %{{.+}}, %{{.+}} : (!cir.ptr<!s64i>, !s64i, !s64i) -> (!s64i, !cir.bool) +// LLVM-LABEL: @test_sync_bool_compare_and_swap_8( +// LLVM: cmpxchg ptr %{{.+}}, i64 %{{.+}}, i64 %{{.+}} seq_cst seq_cst, align 8 +// LLVM: extractvalue { i64, i1 } %{{.+}}, 1 +// OGCG-LABEL: @test_sync_bool_compare_and_swap_8( +// OGCG: cmpxchg ptr %{{.+}}, i64 %{{.+}}, i64 %{{.+}} seq_cst seq_cst, align 8 +// OGCG: extractvalue { i64, i1 } %{{.+}}, 1 +bool test_sync_bool_compare_and_swap_8(long long *p, long long oldv, + long long newv) { + return __sync_bool_compare_and_swap(p, oldv, newv); +} + +// __sync_swap + +// CIR-LABEL: @test_sync_swap_1( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s8i>, !s8i) -> !s8i +// LLVM-LABEL: @test_sync_swap_1( +// LLVM: atomicrmw xchg ptr %{{.+}}, i8 %{{.+}} seq_cst, align 1 +// OGCG-LABEL: @test_sync_swap_1( +// OGCG: atomicrmw xchg ptr %{{.+}}, i8 %{{.+}} seq_cst, align 1 +char test_sync_swap_1(char *p, char val) { + return __sync_swap(p, val); +} + +// CIR-LABEL: @test_sync_swap_2( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s16i>, !s16i) -> !s16i +// LLVM-LABEL: @test_sync_swap_2( +// LLVM: atomicrmw xchg ptr %{{.+}}, i16 %{{.+}} seq_cst, align 2 +// OGCG-LABEL: @test_sync_swap_2( +// OGCG: atomicrmw xchg ptr %{{.+}}, i16 %{{.+}} seq_cst, align 2 +short test_sync_swap_2(short *p, short val) { + return __sync_swap(p, val); +} + +// CIR-LABEL: @test_sync_swap_4( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i +// LLVM-LABEL: @test_sync_swap_4( +// LLVM: atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4 +// OGCG-LABEL: @test_sync_swap_4( +// OGCG: atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4 +int test_sync_swap_4(int *p, int val) { + return __sync_swap(p, val); +} + +// CIR-LABEL: @test_sync_swap_8( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s64i>, !s64i) -> !s64i +// LLVM-LABEL: @test_sync_swap_8( +// LLVM: atomicrmw xchg ptr %{{.+}}, i64 %{{.+}} seq_cst, align 8 +// OGCG-LABEL: @test_sync_swap_8( +// OGCG: atomicrmw xchg ptr %{{.+}}, i64 %{{.+}} seq_cst, align 8 +long long test_sync_swap_8(long long *p, long long val) { + return __sync_swap(p, val); +} + +// __sync_lock_test_and_set + +// CIR-LABEL: @test_sync_lock_test_and_set_1( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s8i>, !s8i) -> !s8i +// LLVM-LABEL: @test_sync_lock_test_and_set_1( +// LLVM: atomicrmw xchg ptr %{{.+}}, i8 %{{.+}} seq_cst, align 1 +// OGCG-LABEL: @test_sync_lock_test_and_set_1( +// OGCG: atomicrmw xchg ptr %{{.+}}, i8 %{{.+}} seq_cst, align 1 +char test_sync_lock_test_and_set_1(char *p, char val) { + return __sync_lock_test_and_set(p, val); +} + +// CIR-LABEL: @test_sync_lock_test_and_set_2( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s16i>, !s16i) -> !s16i +// LLVM-LABEL: @test_sync_lock_test_and_set_2( +// LLVM: atomicrmw xchg ptr %{{.+}}, i16 %{{.+}} seq_cst, align 2 +// OGCG-LABEL: @test_sync_lock_test_and_set_2( +// OGCG: atomicrmw xchg ptr %{{.+}}, i16 %{{.+}} seq_cst, align 2 +short test_sync_lock_test_and_set_2(short *p, short val) { + return __sync_lock_test_and_set(p, val); +} + +// CIR-LABEL: @test_sync_lock_test_and_set_4( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i +// LLVM-LABEL: @test_sync_lock_test_and_set_4( +// LLVM: atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4 +// OGCG-LABEL: @test_sync_lock_test_and_set_4( +// OGCG: atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4 +int test_sync_lock_test_and_set_4(int *p, int val) { + return __sync_lock_test_and_set(p, val); +} + +// CIR-LABEL: @test_sync_lock_test_and_set_8( +// CIR: cir.atomic.xchg seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s64i>, !s64i) -> !s64i +// LLVM-LABEL: @test_sync_lock_test_and_set_8( +// LLVM: atomicrmw xchg ptr %{{.+}}, i64 %{{.+}} seq_cst, align 8 +// OGCG-LABEL: @test_sync_lock_test_and_set_8( +// OGCG: atomicrmw xchg ptr %{{.+}}, i64 %{{.+}} seq_cst, align 8 +long long test_sync_lock_test_and_set_8(long long *p, long long val) { + return __sync_lock_test_and_set(p, val); +} + +// __sync_lock_release + +// CIR-LABEL: @test_sync_lock_release_1( +// CIR: cir.store {{.*}}atomic(release) {{.*}} : !s8i, !cir.ptr<!s8i> +// LLVM-LABEL: @test_sync_lock_release_1( +// LLVM: store atomic i8 0, ptr %{{.+}} release, align 1 +// OGCG-LABEL: @test_sync_lock_release_1( +// OGCG: store atomic i8 0, ptr %{{.+}} release, align 1 +void test_sync_lock_release_1(char *p) { + __sync_lock_release(p); +} + +// CIR-LABEL: @test_sync_lock_release_2( +// CIR: cir.store {{.*}}atomic(release) {{.*}} : !s16i, !cir.ptr<!s16i> +// LLVM-LABEL: @test_sync_lock_release_2( +// LLVM: store atomic i16 0, ptr %{{.+}} release, align 2 +// OGCG-LABEL: @test_sync_lock_release_2( +// OGCG: store atomic i16 0, ptr %{{.+}} release, align 2 +void test_sync_lock_release_2(short *p) { + __sync_lock_release(p); +} + +// CIR-LABEL: @test_sync_lock_release_4( +// CIR: cir.store {{.*}}atomic(release) {{.*}} : !s32i, !cir.ptr<!s32i> +// LLVM-LABEL: @test_sync_lock_release_4( +// LLVM: store atomic i32 0, ptr %{{.+}} release, align 4 +// OGCG-LABEL: @test_sync_lock_release_4( +// OGCG: store atomic i32 0, ptr %{{.+}} release, align 4 +void test_sync_lock_release_4(int *p) { + __sync_lock_release(p); +} + +// CIR-LABEL: @test_sync_lock_release_8( +// CIR: cir.store {{.*}}atomic(release) {{.*}} : !s64i, !cir.ptr<!s64i> +// LLVM-LABEL: @test_sync_lock_release_8( +// LLVM: store atomic i64 0, ptr %{{.+}} release, align 8 +// OGCG-LABEL: @test_sync_lock_release_8( +// OGCG: store atomic i64 0, ptr %{{.+}} release, align 8 +void test_sync_lock_release_8(long long *p) { + __sync_lock_release(p); +} + +} diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp b/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp index 335383c075dac..dac0ddf366334 100644 --- a/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp +++ b/clang/test/CIR/CodeGenBuiltins/builtin-undef-rvalue.cpp @@ -6,7 +6,7 @@ typedef int v4si __attribute__((vector_size(16))); int test_builtin_reduce_add_undef_rvalue(v4si x) { - // expected-error@+1 {{unimplemented X86 builtin call: __builtin_reduce_add}} + // expected-error@+1 {{unimplemented builtin call: __builtin_reduce_add}} return __builtin_reduce_add(x); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
