Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -52,6 +52,8 @@ // LL -> long long // LLL -> __int128_t (e.g. LLLi) // W -> int64_t +// l -> 'int' if builtin is a MS extensions and the target is Darwin/LP64. +// Defaults to 'L' otherwise. // S -> signed // U -> unsigned // I -> Required to constant fold to an integer constant expression. @@ -718,11 +720,11 @@ LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", "stdlib.h", ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_ulong, "ULiULi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) +LIBBUILTIN(_byteswap_ulong, "UliUli", "fnc", "stdlib.h", ALL_MS_LANGUAGES) LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", "stdlib.h", ALL_MS_LANGUAGES) LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__exception_code, "Uli", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_exception_code, "Uli", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__exception_info, "v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES) @@ -730,33 +732,33 @@ LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedAnd16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedAnd, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedAnd, "liliD*li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedCompareExchange, "liliD*lili", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedDecrement16, "ssD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedDecrement, "liliD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange, "liliD*li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchange8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchange16, "ssD*s", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeAdd, "liliD*li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeSub, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeSub, "liliD*li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedIncrement16, "ssD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedIncrement, "liliD*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedOr8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedOr16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedOr, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedOr, "liliD*li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedXor, "LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandset, "UcLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedXor, "liliD*li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_interlockedbittestandset, "UcliD*li", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES) @@ -765,12 +767,12 @@ LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_lrotl, "ULiULii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotl, "UliUlii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr8, "UcUcUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr16, "UsUsUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr, "UiUii", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_lrotr, "ULiULii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_lrotr, "UliUlii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES) Index: include/clang/Basic/BuiltinsARM.def =================================================================== --- include/clang/Basic/BuiltinsARM.def +++ include/clang/Basic/BuiltinsARM.def @@ -215,10 +215,10 @@ LANGBUILTIN(_MoveToCoprocessor, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveToCoprocessor2, "vUiIUiIUiIUiIUiIUi", "", ALL_MS_LANGUAGES) -TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward, "UcUli*Uli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUli*Uli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUli*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUli*ULLi", "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, "") Index: include/clang/Basic/BuiltinsX86.def =================================================================== --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1822,8 +1822,8 @@ TARGET_BUILTIN(__builtin_ia32_clzero, "vv*", "", "clzero") // MSVC -TARGET_HEADER_BUILTIN(_BitScanForward, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse, "UcULi*ULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward, "UcUli*Uli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUli*Uli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_ReadBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") @@ -1838,15 +1838,15 @@ TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readfsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readfsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readfsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readfsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsbyte, "UcUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsword, "UsUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsdword, "UliUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsqword, "ULLiUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readgsbyte, "UcULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readgsword, "UsULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readgsdword, "ULiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__readgsqword, "ULLiULi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsbyte, "UcUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsword, "UsUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsdword, "UliUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsqword, "ULLiUli", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef BUILTIN #undef TARGET_BUILTIN Index: include/clang/Basic/BuiltinsX86_64.def =================================================================== --- include/clang/Basic/BuiltinsX86_64.def +++ include/clang/Basic/BuiltinsX86_64.def @@ -22,8 +22,8 @@ # define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif -TARGET_HEADER_BUILTIN(_BitScanForward64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcULi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUli*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUli*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__mulh, "LLiLLiLLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nch", "intrin.h", ALL_MS_LANGUAGES, "") Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -8513,7 +8513,7 @@ RequiresICE = false; // Read the prefixed modifiers first. - bool Done = false; + bool Done = false, IsSpecialLong = false; while (!Done) { switch (*Str++) { default: Done = true; --Str; break; @@ -8531,12 +8531,29 @@ Unsigned = true; break; case 'L': + assert(!IsSpecialLong && "Can't use 'L' with 'W' or 'l' modifiers"); assert(HowLong <= 2 && "Can't have LLLL modifier"); ++HowLong; break; + case 'l': { + // 'l' behaves like 'L' for all targets but for Darwin/LP64 with + // -fms-extension and Darwin/LP64, where "long" for intrinsic calls must + // match "int", allowing code with MS extensions to target Darwin/LP64. + assert(!IsSpecialLong && "Can't use two 'l' or 'W' modifiers!"); + assert(HowLong == 0 && "Can't use both 'L' and 'l' modifiers!"); + assert(LangOpts.MicrosoftExt && "Unsupported for non MS extension mode") + IsSpecialLong = true; + // We need to be specific for Darwin here, MS extensions on Linux/LP64 + // for instance, do not assume the same constraints. + if (Context.getTargetInfo().getTriple().getOS() != llvm::Triple::Darwin) + ++HowLong; + break; + } case 'W': // This modifier represents int64 type. + assert(!IsSpecialLong && "Can't use two 'l' or 'W' modifiers!"); assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!"); + IsSpecialLong = true; switch (Context.getTargetInfo().getInt64Type()) { default: llvm_unreachable("Unexpected integer type"); Index: test/CodeGen/ms-intrinsics-darwin.c =================================================================== --- /dev/null +++ test/CodeGen/ms-intrinsics-darwin.c @@ -0,0 +1,153 @@ +// RUN: %clang_cc1 -ffreestanding -fms-extensions \ +// RUN: -triple x86_64--darwin -Oz -emit-llvm %s -o - \ +// RUN: | FileCheck %s + +#define LONG int + +unsigned char test_BitScanForward(unsigned LONG *Index, unsigned LONG Mask) { + return _BitScanForward(Index, Mask); +} +// CHECK: define{{.*}}i8 @test_BitScanForward(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i32 %Mask, 0 +// CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] +// CHECK: [[END_LABEL]]: +// CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK: ret i8 [[RESULT]] +// CHECK: [[ISNOTZERO_LABEL]]: +// CHECK: [[INDEX:%[0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %Mask, i1 true) +// CHECK: store i32 [[INDEX]], i32* %Index, align 4 +// CHECK: br label %[[END_LABEL]] + +unsigned char test_BitScanReverse(unsigned LONG *Index, unsigned LONG Mask) { + return _BitScanReverse(Index, Mask); +} +// CHECK: define{{.*}}i8 @test_BitScanReverse(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i32 %Mask, 0 +// CHECK: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] +// CHECK: [[END_LABEL]]: +// CHECK: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK: ret i8 [[RESULT]] +// CHECK: [[ISNOTZERO_LABEL]]: +// CHECK: [[REVINDEX:%[0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %Mask, i1 true) +// CHECK: [[INDEX:%[0-9]+]] = xor i32 [[REVINDEX]], 31 +// CHECK: store i32 [[INDEX]], i32* %Index, align 4 +// CHECK: br label %[[END_LABEL]] + +#if defined(__x86_64__) || defined(__arm__) +unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 Mask) { + return _BitScanForward64(Index, Mask); +} +// CHECK-ARM-X64: define{{.*}}i8 @test_BitScanForward64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK-ARM-X64: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %Mask, 0 +// CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] +// CHECK-ARM-X64: [[END_LABEL]]: +// CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK-ARM-X64: ret i8 [[RESULT]] +// CHECK-ARM-X64: [[ISNOTZERO_LABEL]]: +// CHECK-ARM-X64: [[INDEX:%[0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %Mask, i1 true) +// CHECK-ARM-X64: [[TRUNC_INDEX:%[0-9]+]] = trunc i64 [[INDEX]] to i32 +// CHECK-ARM-X64: store i32 [[TRUNC_INDEX]], i32* %Index, align 4 +// CHECK-ARM-X64: br label %[[END_LABEL]] + +unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 Mask) { + return _BitScanReverse64(Index, Mask); +} +// CHECK-ARM-X64: define{{.*}}i8 @test_BitScanReverse64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK-ARM-X64: [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %Mask, 0 +// CHECK-ARM-X64: br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]] +// CHECK-ARM-X64: [[END_LABEL]]: +// CHECK-ARM-X64: [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ] +// CHECK-ARM-X64: ret i8 [[RESULT]] +// CHECK-ARM-X64: [[ISNOTZERO_LABEL]]: +// CHECK-ARM-X64: [[REVINDEX:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %Mask, i1 true) +// CHECK-ARM-X64: [[TRUNC_REVINDEX:%[0-9]+]] = trunc i64 [[REVINDEX]] to i32 +// CHECK-ARM-X64: [[INDEX:%[0-9]+]] = xor i32 [[TRUNC_REVINDEX]], 63 +// CHECK-ARM-X64: store i32 [[INDEX]], i32* %Index, align 4 +// CHECK-ARM-X64: br label %[[END_LABEL]] +#endif + +LONG test_InterlockedExchange(LONG volatile *value, LONG mask) { + return _InterlockedExchange(value, mask); +} +// CHECK: define{{.*}}i32 @test_InterlockedExchange(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw xchg i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + +LONG test_InterlockedExchangeAdd(LONG volatile *value, LONG mask) { + return _InterlockedExchangeAdd(value, mask); +} +// CHECK: define{{.*}}i32 @test_InterlockedExchangeAdd(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + +LONG test_InterlockedExchangeSub(LONG volatile *value, LONG mask) { + return _InterlockedExchangeSub(value, mask); +} +// CHECK: define{{.*}}i32 @test_InterlockedExchangeSub(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw sub i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + +LONG test_InterlockedOr(LONG volatile *value, LONG mask) { + return _InterlockedOr(value, mask); +} +// CHECK: define{{.*}}i32 @test_InterlockedOr(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw or i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + +LONG test_InterlockedXor(LONG volatile *value, LONG mask) { + return _InterlockedXor(value, mask); +} +// CHECK: define{{.*}}i32 @test_InterlockedXor(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw xor i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + +LONG test_InterlockedAnd(LONG volatile *value, LONG mask) { + return _InterlockedAnd(value, mask); +} +// CHECK: define{{.*}}i32 @test_InterlockedAnd(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{ +// CHECK: [[RESULT:%[0-9]+]] = atomicrmw and i32* %value, i32 %mask seq_cst +// CHECK: ret i32 [[RESULT:%[0-9]+]] +// CHECK: } + +LONG test_InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG Comperand) { + return _InterlockedCompareExchange(Destination, Exchange, Comperand); +} +// CHECK: define{{.*}}i32 @test_InterlockedCompareExchange(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{ +// CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile i32* %Destination, i32 %Comperand, i32 %Exchange seq_cst seq_cst +// CHECK: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0 +// CHECK: ret i32 [[RESULT]] +// CHECK: } + +LONG test_InterlockedIncrement(LONG volatile *Addend) { + return _InterlockedIncrement(Addend); +} +// CHECK: define{{.*}}i32 @test_InterlockedIncrement(i32*{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: [[TMP:%[0-9]+]] = atomicrmw add i32* %Addend, i32 1 seq_cst +// CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1 +// CHECK: ret i32 [[RESULT]] +// CHECK: } + +LONG test_InterlockedDecrement(LONG volatile *Addend) { + return _InterlockedDecrement(Addend); +} +// CHECK: define{{.*}}i32 @test_InterlockedDecrement(i32*{{[a-z_ ]*}}%Addend){{.*}}{ +// CHECK: [[TMP:%[0-9]+]] = atomicrmw sub i32* %Addend, i32 1 seq_cst +// CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 +// CHECK: ret i32 [[RESULT]] +// CHECK: } + +unsigned char test_interlockedbittestandset(volatile LONG *ptr, LONG bit) { + return _interlockedbittestandset(ptr, bit); +} +// CHECK-LABEL: define{{.*}} i8 @test_interlockedbittestandset +// CHECK: [[MASKBIT:%[0-9]+]] = shl i32 1, %bit +// CHECK: [[OLD:%[0-9]+]] = atomicrmw or i32* %ptr, i32 [[MASKBIT]] seq_cst +// CHECK: [[SHIFT:%[0-9]+]] = lshr i32 [[OLD]], %bit +// CHECK: [[TRUNC:%[0-9]+]] = trunc i32 [[SHIFT]] to i8 +// CHECK: [[AND:%[0-9]+]] = and i8 [[TRUNC]], 1 +// CHECK: ret i8 [[AND]]