Skip to content

Commit

Permalink
[COFF][Aarch64] Add _InterlockedAdd64 intrinsic (#81849)
Browse files Browse the repository at this point in the history
Found when compiling openssl master branch using clang-cl.

This commit introduces usage of InterlockedAdd64:

openssl/openssl@d0e1a0a


https://learn.microsoft.com/en-us/cpp/intrinsics/interlockedadd-intrinsic-functions
  • Loading branch information
pbo-linaro committed Feb 16, 2024
1 parent c681ea6 commit 0ea64ad
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 1 deletion.
1 change: 1 addition & 0 deletions clang/include/clang/Basic/BuiltinsAArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LA
TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

TARGET_HEADER_BUILTIN(_InterlockedAdd, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedAdd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12043,7 +12043,8 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
"vgetq_lane");
}

case clang::AArch64::BI_InterlockedAdd: {
case clang::AArch64::BI_InterlockedAdd:
case clang::AArch64::BI_InterlockedAdd64: {
Address DestAddr = CheckAtomicAlignment(*this, E);
Value *Val = EmitScalarExpr(E->getArg(1));
AtomicRMWInst *RMWI =
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Headers/intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,7 @@ static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
#if defined(__aarch64__)
unsigned __int64 __getReg(int);
long _InterlockedAdd(long volatile *Addend, long Value);
__int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value);
__int64 _ReadStatusReg(int);
void _WriteStatusReg(int, __int64);

Expand Down
14 changes: 14 additions & 0 deletions clang/test/CodeGen/arm64-microsoft-intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ long test_InterlockedAdd_constant(long volatile *Addend) {
// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]]
// CHECK-LINUX: error: call to undeclared function '_InterlockedAdd'

__int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) {
return _InterlockedAdd64(Addend, Value);
}

__int64 test_InterlockedAdd64_constant(__int64 volatile *Addend) {
return _InterlockedAdd64(Addend, -1);
}

// CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64(ptr %Addend, i64 %Value) {{.*}} {
// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 seq_cst, 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'

void check__dmb(void) {
__dmb(0);
}
Expand Down
9 changes: 9 additions & 0 deletions clang/test/CodeGen/ms-intrinsics-other.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,15 @@ LONG test_InterlockedAdd(LONG volatile *Addend, LONG Value) {
// CHECK-ARM-ARM64: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %Addend, i32 %Value seq_cst, align 4
// CHECK-ARM-ARM64: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %Value
// CHECK-ARM-ARM64: ret i32 %[[NEWVAL:[0-9]+]]

__int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) {
return _InterlockedAdd64(Addend, Value);
}

// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedAdd64(ptr{{[a-z_ ]*}}%Addend, i64 noundef %Value) {{.*}} {
// CHECK-ARM-ARM64: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %Addend, i64 %Value seq_cst, align 8
// CHECK-ARM-ARM64: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %Value
// CHECK-ARM-ARM64: ret i64 %[[NEWVAL:[0-9]+]]
#endif

#if defined(__arm__) || defined(__aarch64__)
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CodeGen/ms-intrinsics-underaligned.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,10 @@ long long test_InterlockedCompareExchange64(X *x) {
long test_InterlockedAdd(X *x) {
return _InterlockedAdd(&x->c, 4);
}

// CHECK-AARCH64-LABEL: @test_InterlockedAdd64(
// CHECK-AARCH64: atomicrmw {{.*}} align 8
long test_InterlockedAdd64(X *x) {
return _InterlockedAdd64(&x->c, 4);
}
#endif

0 comments on commit 0ea64ad

Please sign in to comment.