From: Mandeep Singh Grang Date: Fri, 5 Oct 2018 21:57:41 +0000 (+0000) Subject: [COFF, ARM64] Add _InterlockedAdd intrinsic X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=339ff47af8084b99b9968f078e66f62d6adfafab;p=clang [COFF, ARM64] Add _InterlockedAdd intrinsic Reviewers: rnk, mstorsjo, compnerd, TomTan, haripul, javed.absar, efriedma Reviewed By: efriedma Subscribers: efriedma, kristof.beyls, chrib, jfb, cfe-commits Differential Revision: https://reviews.llvm.org/D52811 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@343894 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def index 2b6fcdabdc..49bf8313df 100644 --- a/include/clang/Basic/BuiltinsAArch64.def +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -94,6 +94,7 @@ TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LAN TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd, "LiLiD*Li", "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, "") diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 8e23b22f78..18b300bf11 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -8517,6 +8517,15 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); case AArch64::BI_InterlockedIncrement64: return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); + + case AArch64::BI_InterlockedAdd: { + Value *Arg0 = EmitScalarExpr(E->getArg(0)); + Value *Arg1 = EmitScalarExpr(E->getArg(1)); + AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( + AtomicRMWInst::Add, Arg0, Arg1, + llvm::AtomicOrdering::SequentiallyConsistent); + return Builder.CreateAdd(RMWI, Arg1); + } } } diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h index c5b4ff4d7d..6f753ba125 100644 --- a/lib/Headers/intrin.h +++ b/lib/Headers/intrin.h @@ -869,6 +869,7 @@ __nop(void) { \*----------------------------------------------------------------------------*/ #if defined(__aarch64__) unsigned __int64 __getReg(int); +long _InterlockedAdd(long volatile *Addend, long Value); #endif /*----------------------------------------------------------------------------*\ diff --git a/test/CodeGen/arm64-microsoft-intrinsics.c b/test/CodeGen/arm64-microsoft-intrinsics.c index c8516079eb..eeb09e8972 100644 --- a/test/CodeGen/arm64-microsoft-intrinsics.c +++ b/test/CodeGen/arm64-microsoft-intrinsics.c @@ -4,6 +4,16 @@ // RUN: not %clang_cc1 -triple arm64-linux -Werror -S -o /dev/null %s 2>&1 \ // RUN: | FileCheck %s -check-prefix CHECK-LINUX +long test_InterlockedAdd(long volatile *Addend, long Value) { + return _InterlockedAdd(Addend, Value); +} + +// CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd(i32* %Addend, i32 %Value) {{.*}} { +// CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add i32* %1, i32 %2 seq_cst +// CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2 +// CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]] +// CHECK-LINUX: error: implicit declaration of function '_InterlockedAdd' + void check__dmb(void) { __dmb(0); }