Index: include/clang/Basic/BuiltinsAArch64.def =================================================================== --- include/clang/Basic/BuiltinsAArch64.def +++ include/clang/Basic/BuiltinsAArch64.def @@ -104,6 +104,19 @@ 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(_InterlockedExchangeAdd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Index: include/clang/Basic/BuiltinsARM.def =================================================================== --- include/clang/Basic/BuiltinsARM.def +++ include/clang/Basic/BuiltinsARM.def @@ -230,6 +230,19 @@ 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(_InterlockedExchangeAdd_acq, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_rel, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd_nf, "LiLiD*Li", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_acq, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_rel, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd16_nf, "ssD*s", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_acq, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_rel, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64_nf, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN #undef TARGET_HEADER_BUILTIN Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -95,9 +95,9 @@ /// Utility to insert an atomic instruction based on Instrinsic::ID /// and the expression node. -static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF, - llvm::AtomicRMWInst::BinOp Kind, - const CallExpr *E) { +static Value *MakeBinaryAtomicValue( + CodeGenFunction &CGF, llvm::AtomicRMWInst::BinOp Kind, const CallExpr *E, + AtomicOrdering Ordering = AtomicOrdering::SequentiallyConsistent) { QualType T = E->getType(); assert(E->getArg(0)->getType()->isPointerType()); assert(CGF.getContext().hasSameUnqualifiedType(T, @@ -119,7 +119,7 @@ Args[1] = EmitToInt(CGF, Args[1], T, IntType); llvm::Value *Result = CGF.Builder.CreateAtomicRMW( - Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); + Kind, Args[0], Args[1], Ordering); return EmitFromInt(CGF, Result, T, ValueType); } @@ -745,6 +745,18 @@ _InterlockedIncrement, _InterlockedOr, _InterlockedXor, + _InterlockedExchangeAdd8_acq, + _InterlockedExchangeAdd8_rel, + _InterlockedExchangeAdd8_nf, + _InterlockedExchangeAdd16_acq, + _InterlockedExchangeAdd16_rel, + _InterlockedExchangeAdd16_nf, + _InterlockedExchangeAdd_acq, + _InterlockedExchangeAdd_rel, + _InterlockedExchangeAdd_nf, + _InterlockedExchangeAdd64_acq, + _InterlockedExchangeAdd64_rel, + _InterlockedExchangeAdd64_nf, __fastfail, }; @@ -812,6 +824,27 @@ case MSVCIntrin::_InterlockedXor: return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E); + case MSVCIntrin::_InterlockedExchangeAdd8_acq: + case MSVCIntrin::_InterlockedExchangeAdd16_acq: + case MSVCIntrin::_InterlockedExchangeAdd_acq: + case MSVCIntrin::_InterlockedExchangeAdd64_acq: + return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E, + AtomicOrdering::Acquire); + + case MSVCIntrin::_InterlockedExchangeAdd8_rel: + case MSVCIntrin::_InterlockedExchangeAdd16_rel: + case MSVCIntrin::_InterlockedExchangeAdd_rel: + case MSVCIntrin::_InterlockedExchangeAdd64_rel: + return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E, + AtomicOrdering::Release); + + case MSVCIntrin::_InterlockedExchangeAdd8_nf: + case MSVCIntrin::_InterlockedExchangeAdd16_nf: + case MSVCIntrin::_InterlockedExchangeAdd_nf: + case MSVCIntrin::_InterlockedExchangeAdd64_nf: + return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E, + AtomicOrdering::Monotonic); + case MSVCIntrin::_InterlockedDecrement: { llvm::Type *IntTy = ConvertType(E->getType()); AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( @@ -6109,6 +6142,30 @@ return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); case ARM::BI_InterlockedIncrement64: return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); + case ARM::BI_InterlockedExchangeAdd8_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd8_acq, E); + case ARM::BI_InterlockedExchangeAdd8_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd8_rel, E); + case ARM::BI_InterlockedExchangeAdd8_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd8_nf, E); + case ARM::BI_InterlockedExchangeAdd16_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd16_acq, E); + case ARM::BI_InterlockedExchangeAdd16_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd16_rel, E); + case ARM::BI_InterlockedExchangeAdd16_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd16_nf, E); + case ARM::BI_InterlockedExchangeAdd_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_acq, E); + case ARM::BI_InterlockedExchangeAdd_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_rel, E); + case ARM::BI_InterlockedExchangeAdd_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_nf, E); + case ARM::BI_InterlockedExchangeAdd64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd64_acq, E); + case ARM::BI_InterlockedExchangeAdd64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd64_rel, E); + case ARM::BI_InterlockedExchangeAdd64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd64_nf, E); } // Get the last argument, which specifies the vector type. @@ -8590,6 +8647,30 @@ return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); case AArch64::BI_InterlockedIncrement64: return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); + case AArch64::BI_InterlockedExchangeAdd8_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd8_acq, E); + case AArch64::BI_InterlockedExchangeAdd8_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd8_rel, E); + case AArch64::BI_InterlockedExchangeAdd8_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd8_nf, E); + case AArch64::BI_InterlockedExchangeAdd16_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd16_acq, E); + case AArch64::BI_InterlockedExchangeAdd16_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd16_rel, E); + case AArch64::BI_InterlockedExchangeAdd16_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd16_nf, E); + case AArch64::BI_InterlockedExchangeAdd_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_acq, E); + case AArch64::BI_InterlockedExchangeAdd_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_rel, E); + case AArch64::BI_InterlockedExchangeAdd_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd_nf, E); + case AArch64::BI_InterlockedExchangeAdd64_acq: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd64_acq, E); + case AArch64::BI_InterlockedExchangeAdd64_rel: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd64_rel, E); + case AArch64::BI_InterlockedExchangeAdd64_nf: + return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd64_nf, E); case AArch64::BI_InterlockedAdd: { Value *Arg0 = EmitScalarExpr(E->getArg(0)); Index: lib/Headers/intrin.h =================================================================== --- lib/Headers/intrin.h +++ lib/Headers/intrin.h @@ -329,54 +329,18 @@ |* Interlocked Exchange Add \*----------------------------------------------------------------------------*/ #if defined(__arm__) || defined(__aarch64__) -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd8_acq(char volatile *_Addend, char _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_ACQUIRE); -} -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd8_nf(char volatile *_Addend, char _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELAXED); -} -static __inline__ char __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd8_rel(char volatile *_Addend, char _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELAXED); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd16_acq(short volatile *_Addend, short _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_ACQUIRE); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd16_nf(short volatile *_Addend, short _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELAXED); -} -static __inline__ short __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd16_rel(short volatile *_Addend, short _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELEASE); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd_acq(long volatile *_Addend, long _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_ACQUIRE); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd_nf(long volatile *_Addend, long _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELAXED); -} -static __inline__ long __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELEASE); -} -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_ACQUIRE); -} -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64_nf(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELAXED); -} -static __inline__ __int64 __DEFAULT_FN_ATTRS -_InterlockedExchangeAdd64_rel(__int64 volatile *_Addend, __int64 _Value) { - return __atomic_fetch_add(_Addend, _Value, __ATOMIC_RELEASE); -} +char _InterlockedExchangeAdd8_acq(char volatile *_Addend, char _Value); +char _InterlockedExchangeAdd8_nf(char volatile *_Addend, char _Value); +char _InterlockedExchangeAdd8_rel(char volatile *_Addend, char _Value); +short _InterlockedExchangeAdd16_acq(short volatile *_Addend, short _Value); +short _InterlockedExchangeAdd16_nf(short volatile *_Addend, short _Value); +short _InterlockedExchangeAdd16_rel(short volatile *_Addend, short _Value); +long _InterlockedExchangeAdd_acq(long volatile *_Addend, long _Value); +long _InterlockedExchangeAdd_nf(long volatile *_Addend, long _Value); +long _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value); +__int64 _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value); +__int64 _InterlockedExchangeAdd64_nf(__int64 volatile *_Addend, __int64 _Value); +__int64 _InterlockedExchangeAdd64_rel(__int64 volatile *_Addend, __int64 _Value); #endif /*----------------------------------------------------------------------------*\ |* Interlocked Increment Index: test/CodeGen/ms-intrinsics.c =================================================================== --- test/CodeGen/ms-intrinsics.c +++ test/CodeGen/ms-intrinsics.c @@ -3,13 +3,13 @@ // RUN: | FileCheck %s -check-prefixes CHECK,CHECK-I386,CHECK-INTEL // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple thumbv7--windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-X64 +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-ARM64,CHECK-ARM-X64 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple x86_64--windows -Oz -emit-llvm -target-feature +cx16 %s -o - \ // RUN: | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple aarch64-windows -Oz -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefix CHECK-ARM-X64 +// RUN: | FileCheck %s --check-prefixes CHECK-ARM-ARM64,CHECK-ARM-X64 // intrin.h needs size_t, but -ffreestanding prevents us from getting it from // stddef.h. Work around it with this typedef. @@ -612,6 +612,94 @@ } #endif +#if defined(__arm__) || defined(__aarch64__) +char test_InterlockedExchangeAdd8_acq(char volatile *value, char mask) { + return _InterlockedExchangeAdd8_acq(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_acq(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask acquire +// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +char test_InterlockedExchangeAdd8_rel(char volatile *value, char mask) { + return _InterlockedExchangeAdd8_rel(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_rel(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask release +// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +char test_InterlockedExchangeAdd8_nf(char volatile *value, char mask) { + return _InterlockedExchangeAdd8_nf(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i8 @test_InterlockedExchangeAdd8_nf(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask monotonic +// CHECK-ARM-ARM64: ret i8 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +short test_InterlockedExchangeAdd16_acq(short volatile *value, short mask) { + return _InterlockedExchangeAdd16_acq(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_acq(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask acquire +// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +short test_InterlockedExchangeAdd16_rel(short volatile *value, short mask) { + return _InterlockedExchangeAdd16_rel(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_rel(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask release +// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +short test_InterlockedExchangeAdd16_nf(short volatile *value, short mask) { + return _InterlockedExchangeAdd16_nf(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i16 @test_InterlockedExchangeAdd16_nf(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask monotonic +// CHECK-ARM-ARM64: ret i16 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +long test_InterlockedExchangeAdd_acq(long volatile *value, long mask) { + return _InterlockedExchangeAdd_acq(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_acq(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask acquire +// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +long test_InterlockedExchangeAdd_rel(long volatile *value, long mask) { + return _InterlockedExchangeAdd_rel(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_rel(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask release +// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +long test_InterlockedExchangeAdd_nf(long volatile *value, long mask) { + return _InterlockedExchangeAdd_nf(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i32 @test_InterlockedExchangeAdd_nf(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask monotonic +// CHECK-ARM-ARM64: ret i32 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +__int64 test_InterlockedExchangeAdd64_acq(__int64 volatile *value, __int64 mask) { + return _InterlockedExchangeAdd64_acq(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_acq(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask acquire +// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +__int64 test_InterlockedExchangeAdd64_rel(__int64 volatile *value, __int64 mask) { + return _InterlockedExchangeAdd64_rel(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_rel(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask release +// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } +__int64 test_InterlockedExchangeAdd64_nf(__int64 volatile *value, __int64 mask) { + return _InterlockedExchangeAdd64_nf(value, mask); +} +// CHECK-ARM-ARM64: define{{.*}}i64 @test_InterlockedExchangeAdd64_nf(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK-ARM-ARM64: [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask monotonic +// CHECK-ARM-ARM64: ret i64 [[RESULT:%[0-9]+]] +// CHECK-ARM-ARM64: } + +#endif + #if !defined(__aarch64__) void test__fastfail() { __fastfail(42);