Skip to content

InterlockedAdd_*, InterlockedAdd64_* support for AArch64 #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/BuiltinsAArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -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, "")
Expand Down
32 changes: 29 additions & 3 deletions clang/lib/CodeGen/TargetBuiltins/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Headers/intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
60 changes: 60 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,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);
}
Expand All @@ -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();
}
Expand Down