Skip to content

Commit d9a7b16

Browse files
authored
InterlockedAdd_*, InterlockedAdd64_* support for AArch64 (#145607)
This PR adds support for InterlockedAdd_{acq, nf, rel}, and InterlockedAdd64_{acq, nf, rel} for Aarch64.
1 parent aec8867 commit d9a7b16

File tree

4 files changed

+104
-5
lines changed

4 files changed

+104
-5
lines changed

clang/include/clang/Basic/BuiltinsAArch64.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,13 @@ TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", INTRIN_H,
155155
TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
156156
TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
157157

158+
TARGET_HEADER_BUILTIN(_InterlockedAdd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
159+
TARGET_HEADER_BUILTIN(_InterlockedAdd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
160+
TARGET_HEADER_BUILTIN(_InterlockedAdd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
161+
TARGET_HEADER_BUILTIN(_InterlockedAdd64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
162+
TARGET_HEADER_BUILTIN(_InterlockedAdd64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
163+
TARGET_HEADER_BUILTIN(_InterlockedAdd64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
164+
158165
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_acq, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
159166
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
160167
TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

clang/lib/CodeGen/TargetBuiltins/ARM.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6499,12 +6499,38 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
64996499
}
65006500

65016501
case clang::AArch64::BI_InterlockedAdd:
6502-
case clang::AArch64::BI_InterlockedAdd64: {
6502+
case clang::AArch64::BI_InterlockedAdd_acq:
6503+
case clang::AArch64::BI_InterlockedAdd_rel:
6504+
case clang::AArch64::BI_InterlockedAdd_nf:
6505+
case clang::AArch64::BI_InterlockedAdd64:
6506+
case clang::AArch64::BI_InterlockedAdd64_acq:
6507+
case clang::AArch64::BI_InterlockedAdd64_rel:
6508+
case clang::AArch64::BI_InterlockedAdd64_nf: {
65036509
Address DestAddr = CheckAtomicAlignment(*this, E);
65046510
Value *Val = EmitScalarExpr(E->getArg(1));
6511+
llvm::AtomicOrdering Ordering;
6512+
switch (BuiltinID) {
6513+
case clang::AArch64::BI_InterlockedAdd:
6514+
case clang::AArch64::BI_InterlockedAdd64:
6515+
Ordering = llvm::AtomicOrdering::SequentiallyConsistent;
6516+
break;
6517+
case clang::AArch64::BI_InterlockedAdd_acq:
6518+
case clang::AArch64::BI_InterlockedAdd64_acq:
6519+
Ordering = llvm::AtomicOrdering::Acquire;
6520+
break;
6521+
case clang::AArch64::BI_InterlockedAdd_rel:
6522+
case clang::AArch64::BI_InterlockedAdd64_rel:
6523+
Ordering = llvm::AtomicOrdering::Release;
6524+
break;
6525+
case clang::AArch64::BI_InterlockedAdd_nf:
6526+
case clang::AArch64::BI_InterlockedAdd64_nf:
6527+
Ordering = llvm::AtomicOrdering::Monotonic;
6528+
break;
6529+
default:
6530+
llvm_unreachable("missing builtin ID in switch!");
6531+
}
65056532
AtomicRMWInst *RMWI =
6506-
Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val,
6507-
llvm::AtomicOrdering::SequentiallyConsistent);
6533+
Builder.CreateAtomicRMW(AtomicRMWInst::Add, DestAddr, Val, Ordering);
65086534
return Builder.CreateAdd(RMWI, Val);
65096535
}
65106536
}

clang/lib/Headers/intrin.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,14 @@ static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
370370
\*----------------------------------------------------------------------------*/
371371
#if defined(__aarch64__) || defined(__arm64ec__)
372372
unsigned __int64 __getReg(int);
373-
long _InterlockedAdd(long volatile *Addend, long Value);
374-
__int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value);
373+
long _InterlockedAdd(long volatile *, long);
374+
long _InterlockedAdd_acq(long volatile *, long);
375+
long _InterlockedAdd_nf(long volatile *, long);
376+
long _InterlockedAdd_rel(long volatile *, long);
377+
__int64 _InterlockedAdd64(__int64 volatile *, __int64);
378+
__int64 _InterlockedAdd64_acq(__int64 volatile *, __int64);
379+
__int64 _InterlockedAdd64_nf(__int64 volatile *, __int64);
380+
__int64 _InterlockedAdd64_rel(__int64 volatile *, __int64);
375381
__int64 _ReadStatusReg(int);
376382
void _WriteStatusReg(int, __int64);
377383

clang/test/CodeGen/arm64-microsoft-intrinsics.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,36 @@ long test_InterlockedAdd_constant(long volatile *Addend) {
2121
// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]]
2222
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd'
2323

24+
long test_InterlockedAdd_acq(long volatile *Addend, long Value) {
25+
return _InterlockedAdd_acq(Addend, Value);
26+
}
27+
28+
// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd_acq(ptr %Addend, i32 %Value) {{.*}} {
29+
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 acquire, align 4
30+
// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2
31+
// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]]
32+
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd_acq'
33+
34+
long test_InterlockedAdd_nf(long volatile *Addend, long Value) {
35+
return _InterlockedAdd_nf(Addend, Value);
36+
}
37+
38+
// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd_nf(ptr %Addend, i32 %Value) {{.*}} {
39+
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 monotonic, align 4
40+
// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2
41+
// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]]
42+
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd_nf'
43+
44+
long test_InterlockedAdd_rel(long volatile *Addend, long Value) {
45+
return _InterlockedAdd_rel(Addend, Value);
46+
}
47+
48+
// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd_rel(ptr %Addend, i32 %Value) {{.*}} {
49+
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 release, align 4
50+
// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2
51+
// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]]
52+
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd_rel'
53+
2454
__int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) {
2555
return _InterlockedAdd64(Addend, Value);
2656
}
@@ -35,6 +65,36 @@ __int64 test_InterlockedAdd64_constant(__int64 volatile *Addend) {
3565
// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]]
3666
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64'
3767

68+
__int64 test_InterlockedAdd64_acq(__int64 volatile *Addend, __int64 Value) {
69+
return _InterlockedAdd64_acq(Addend, Value);
70+
}
71+
72+
// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64_acq(ptr %Addend, i64 %Value) {{.*}} {
73+
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 acquire, align 8
74+
// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2
75+
// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]]
76+
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64_acq'
77+
78+
__int64 test_InterlockedAdd64_nf(__int64 volatile *Addend, __int64 Value) {
79+
return _InterlockedAdd64_nf(Addend, Value);
80+
}
81+
82+
// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64_nf(ptr %Addend, i64 %Value) {{.*}} {
83+
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 monotonic, align 8
84+
// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2
85+
// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]]
86+
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64_nf'
87+
88+
__int64 test_InterlockedAdd64_rel(__int64 volatile *Addend, __int64 Value) {
89+
return _InterlockedAdd64_rel(Addend, Value);
90+
}
91+
92+
// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64_rel(ptr %Addend, i64 %Value) {{.*}} {
93+
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 release, align 8
94+
// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2
95+
// CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]]
96+
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64_rel'
97+
3898
void check_ReadWriteBarrier(void) {
3999
_ReadWriteBarrier();
40100
}

0 commit comments

Comments
 (0)