[clang] d9a7b16 - InterlockedAdd_*, InterlockedAdd64_* support for AArch64 (#145607)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 25 12:09:33 PDT 2025
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();
}
More information about the cfe-commits
mailing list