Author: Adam Glass Date: 2025-06-25T12:09:30-07:00 New Revision: d9a7b1647984dd6f7059069fcffe23dc1d1438b1
URL: https://github.com/llvm/llvm-project/commit/d9a7b1647984dd6f7059069fcffe23dc1d1438b1 DIFF: https://github.com/llvm/llvm-project/commit/d9a7b1647984dd6f7059069fcffe23dc1d1438b1.diff LOG: InterlockedAdd_*, InterlockedAdd64_* support for AArch64 (#145607) This PR adds support for InterlockedAdd_{acq, nf, rel}, and InterlockedAdd64_{acq, nf, rel} for Aarch64. Added: Modified: clang/include/clang/Basic/BuiltinsAArch64.def clang/lib/CodeGen/TargetBuiltins/ARM.cpp clang/lib/Headers/intrin.h clang/test/CodeGen/arm64-microsoft-intrinsics.c Removed: ################################################################################ diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 8867a9fe09fb9..909e35792b461 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -155,6 +155,13 @@ TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", INTRIN_H, TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") + TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index 6738d4be6dd21..e30a8c6133055 100644 --- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -6499,12 +6499,38 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, } case clang::AArch64::BI_InterlockedAdd: - case clang::AArch64::BI_InterlockedAdd64: { + case clang::AArch64::BI_InterlockedAdd_acq: + case clang::AArch64::BI_InterlockedAdd_rel: + case clang::AArch64::BI_InterlockedAdd_nf: + case clang::AArch64::BI_InterlockedAdd64: + case clang::AArch64::BI_InterlockedAdd64_acq: + case clang::AArch64::BI_InterlockedAdd64_rel: + case clang::AArch64::BI_InterlockedAdd64_nf: { Address DestAddr = CheckAtomicAlignment(*this, E); Value *Val = EmitScalarExpr(E->getArg(1)); + llvm::AtomicOrdering Ordering; + switch (BuiltinID) { + case clang::AArch64::BI_InterlockedAdd: + case clang::AArch64::BI_InterlockedAdd64: + Ordering = llvm::AtomicOrdering::SequentiallyConsistent; + break; + case clang::AArch64::BI_InterlockedAdd_acq: + case clang::AArch64::BI_InterlockedAdd64_acq: + Ordering = llvm::AtomicOrdering::Acquire; + break; + case clang::AArch64::BI_InterlockedAdd_rel: + case clang::AArch64::BI_InterlockedAdd64_rel: + Ordering = llvm::AtomicOrdering::Release; + break; + case clang::AArch64::BI_InterlockedAdd_nf: + case clang::AArch64::BI_InterlockedAdd64_nf: + Ordering = llvm::AtomicOrdering::Monotonic; + break; + default: + llvm_unreachable("missing builtin ID in switch!"); + } AtomicRMWInst *RMWI = - Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, - llvm::AtomicOrdering::SequentiallyConsistent); + Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, Ordering); return Builder.CreateAdd(RMWI, Val); } } diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index 3dd1eb45817d4..39ccc97540b1e 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -370,8 +370,14 @@ static __inline__ void __DEFAULT_FN_ATTRS __nop(void) { \*----------------------------------------------------------------------------*/ #if defined(__aarch64__) || defined(__arm64ec__) unsigned __int64 __getReg(int); -long _InterlockedAdd(long volatile *Addend, long Value); -__int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value); +long _InterlockedAdd(long volatile *, long); +long _InterlockedAdd_acq(long volatile *, long); +long _InterlockedAdd_nf(long volatile *, long); +long _InterlockedAdd_rel(long volatile *, long); +__int64 _InterlockedAdd64(__int64 volatile *, __int64); +__int64 _InterlockedAdd64_acq(__int64 volatile *, __int64); +__int64 _InterlockedAdd64_nf(__int64 volatile *, __int64); +__int64 _InterlockedAdd64_rel(__int64 volatile *, __int64); __int64 _ReadStatusReg(int); void _WriteStatusReg(int, __int64); diff --git a/clang/test/CodeGen/arm64-microsoft-intrinsics.c b/clang/test/CodeGen/arm64-microsoft-intrinsics.c index e18977a4559b1..51e0038b64cde 100644 --- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c +++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c @@ -21,6 +21,36 @@ long test_InterlockedAdd_constant(long volatile *Addend) { // CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]] // CHECK-LINUX: error: call to undeclared function '_InterlockedAdd' +long test_InterlockedAdd_acq(long volatile *Addend, long Value) { + return _InterlockedAdd_acq(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd_acq(ptr %Addend, i32 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 acquire, align 4 +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd_acq' + +long test_InterlockedAdd_nf(long volatile *Addend, long Value) { + return _InterlockedAdd_nf(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd_nf(ptr %Addend, i32 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 monotonic, align 4 +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd_nf' + +long test_InterlockedAdd_rel(long volatile *Addend, long Value) { + return _InterlockedAdd_rel(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd_rel(ptr %Addend, i32 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 release, align 4 +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd_rel' + __int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) { return _InterlockedAdd64(Addend, Value); } @@ -35,6 +65,36 @@ __int64 test_InterlockedAdd64_constant(__int64 volatile *Addend) { // CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]] // CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64' +__int64 test_InterlockedAdd64_acq(__int64 volatile *Addend, __int64 Value) { + return _InterlockedAdd64_acq(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64_acq(ptr %Addend, i64 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 acquire, align 8 +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64_acq' + +__int64 test_InterlockedAdd64_nf(__int64 volatile *Addend, __int64 Value) { + return _InterlockedAdd64_nf(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64_nf(ptr %Addend, i64 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 monotonic, align 8 +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64_nf' + +__int64 test_InterlockedAdd64_rel(__int64 volatile *Addend, __int64 Value) { + return _InterlockedAdd64_rel(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64_rel(ptr %Addend, i64 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 release, align 8 +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64_rel' + void check_ReadWriteBarrier(void) { _ReadWriteBarrier(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits