Index: cfe/trunk/include/clang/Basic/Builtins.def =================================================================== --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -52,6 +52,7 @@ // LL -> long long // LLL -> __int128_t (e.g. LLLi) // W -> int64_t +// N -> 'int' size if target is LP64, 'L' otherwise. // S -> signed // U -> unsigned // I -> Required to constant fold to an integer constant expression. @@ -718,11 +719,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, "UNiUNi", "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, "UNi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_exception_code, "UNi", "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 +731,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, "NiNiD*Ni", "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, "NiNiD*NiNi", "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, "NiNiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange, "NiNiD*Ni", "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, "NiNiD*Ni", "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, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedIncrement16, "ssD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedIncrement, "NiNiD*", "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, "NiNiD*Ni", "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, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_interlockedbittestandset, "UcNiD*Ni", "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 +766,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, "UNiUNii", "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, "UNiUNii", "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: cfe/trunk/include/clang/Basic/BuiltinsARM.def =================================================================== --- cfe/trunk/include/clang/Basic/BuiltinsARM.def +++ cfe/trunk/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, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +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(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Index: cfe/trunk/include/clang/Basic/BuiltinsX86.def =================================================================== --- cfe/trunk/include/clang/Basic/BuiltinsX86.def +++ cfe/trunk/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, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "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(__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(__readfsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsdword, "UNiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readfsqword, "ULLiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + +TARGET_HEADER_BUILTIN(__readgsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsdword, "UNiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__readgsqword, "ULLiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") #undef BUILTIN #undef TARGET_BUILTIN Index: cfe/trunk/include/clang/Basic/BuiltinsX86_64.def =================================================================== --- cfe/trunk/include/clang/Basic/BuiltinsX86_64.def +++ cfe/trunk/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, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*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: cfe/trunk/lib/AST/ASTContext.cpp =================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp +++ cfe/trunk/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,24 @@ Unsigned = true; break; case 'L': + assert(!IsSpecialLong && "Can't use 'L' with 'W' or 'N' modifiers"); assert(HowLong <= 2 && "Can't have LLLL modifier"); ++HowLong; break; + case 'N': { + // 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise. + assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!"); + assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!"); + IsSpecialLong = true; + if (Context.getTargetInfo().getLongWidth() == 32) + ++HowLong; + break; + } case 'W': // This modifier represents int64 type. + assert(!IsSpecialLong && "Can't use two 'N' 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: cfe/trunk/test/CodeGen/ms-intrinsics-other.c =================================================================== --- cfe/trunk/test/CodeGen/ms-intrinsics-other.c +++ cfe/trunk/test/CodeGen/ms-intrinsics-other.c @@ -0,0 +1,161 @@ +// RUN: %clang_cc1 -ffreestanding -fms-extensions \ +// RUN: -triple x86_64--darwin -Oz -emit-llvm %s -o - \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -ffreestanding -fms-extensions \ +// RUN: -triple x86_64--linux -Oz -emit-llvm %s -o - \ +// RUN: | FileCheck %s + +// LP64 targets use 'long' as 'int' for MS intrinsics (-fms-extensions) +#ifdef __LP64__ +#define LONG int +#else +#define LONG long +#endif + +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__) +unsigned char test_BitScanForward64(unsigned LONG *Index, unsigned __int64 Mask) { + return _BitScanForward64(Index, Mask); +} +// CHECK: define{{.*}}i8 @test_BitScanForward64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %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 i64 @llvm.cttz.i64(i64 %Mask, i1 true) +// CHECK: [[TRUNC_INDEX:%[0-9]+]] = trunc i64 [[INDEX]] to i32 +// CHECK: store i32 [[TRUNC_INDEX]], i32* %Index, align 4 +// CHECK: br label %[[END_LABEL]] + +unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 Mask) { + return _BitScanReverse64(Index, Mask); +} +// CHECK: define{{.*}}i8 @test_BitScanReverse64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{ +// CHECK: [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %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 i64 @llvm.ctlz.i64(i64 %Mask, i1 true) +// CHECK: [[TRUNC_REVINDEX:%[0-9]+]] = trunc i64 [[REVINDEX]] to i32 +// CHECK: [[INDEX:%[0-9]+]] = xor i32 [[TRUNC_REVINDEX]], 63 +// CHECK: store i32 [[INDEX]], i32* %Index, align 4 +// CHECK: 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]] Index: cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c =================================================================== --- cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c +++ cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c @@ -12,7 +12,17 @@ // RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \ // RUN: -triple x86_64--linux -emit-llvm %s -o - \ -// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -fms-extensions \ +// RUN: -triple x86_64--darwin -emit-llvm %s -o - \ +// RUN: | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG + +// LP64 targets use 'long' as 'int' for MS intrinsics (-fms-extensions) +#ifdef __LP64__ +#define LONG int +#else +#define LONG long +#endif // rotate left @@ -58,7 +68,7 @@ // CHECK: ret i32 [[RESULT]] // CHECK } -unsigned long test_lrotl(unsigned long value, int shift) { +unsigned LONG test_lrotl(unsigned LONG value, int shift) { return _lrotl(value, shift); } // CHECK-32BIT-LONG: i32 @test_lrotl @@ -72,17 +82,6 @@ // CHECK-32BIT-LONG: ret i32 [[RESULT]] // CHECK-32BIT-LONG } -// CHECK-64BIT-LONG: i64 @test_lrotl -// CHECK-64BIT-LONG: [[SHIFT:%[0-9]+]] = and i64 %{{[0-9]+}}, 63 -// CHECK-64BIT-LONG: [[NEGSHIFT:%[0-9]+]] = sub i64 64, [[SHIFT]] -// CHECK-64BIT-LONG: [[HIGH:%[0-9]+]] = shl i64 [[VALUE:%[0-9]+]], [[SHIFT]] -// CHECK-64BIT-LONG: [[LOW:%[0-9]+]] = lshr i64 [[VALUE]], [[NEGSHIFT]] -// CHECK-64BIT-LONG: [[ROTATED:%[0-9]+]] = or i64 [[HIGH]], [[LOW]] -// CHECK-64BIT-LONG: [[ISZERO:%[0-9]+]] = icmp eq i64 [[SHIFT]], 0 -// CHECK-64BIT-LONG: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i64 [[VALUE]], i64 [[ROTATED]] -// CHECK-64BIT-LONG: ret i64 [[RESULT]] -// CHECK-64BIT-LONG } - unsigned __int64 test_rotl64(unsigned __int64 value, int shift) { return _rotl64(value, shift); } @@ -141,7 +140,7 @@ // CHECK: ret i32 [[RESULT]] // CHECK } -unsigned long test_lrotr(unsigned long value, int shift) { +unsigned LONG test_lrotr(unsigned LONG value, int shift) { return _lrotr(value, shift); } // CHECK-32BIT-LONG: i32 @test_lrotr @@ -155,17 +154,6 @@ // CHECK-32BIT-LONG: ret i32 [[RESULT]] // CHECK-32BIT-LONG } -// CHECK-64BIT-LONG: i64 @test_lrotr -// CHECK-64BIT-LONG: [[SHIFT:%[0-9]+]] = and i64 %{{[0-9]+}}, 63 -// CHECK-64BIT-LONG: [[NEGSHIFT:%[0-9]+]] = sub i64 64, [[SHIFT]] -// CHECK-64BIT-LONG: [[LOW:%[0-9]+]] = lshr i64 [[VALUE:%[0-9]+]], [[SHIFT]] -// CHECK-64BIT-LONG: [[HIGH:%[0-9]+]] = shl i64 [[VALUE]], [[NEGSHIFT]] -// CHECK-64BIT-LONG: [[ROTATED:%[0-9]+]] = or i64 [[HIGH]], [[LOW]] -// CHECK-64BIT-LONG: [[ISZERO:%[0-9]+]] = icmp eq i64 [[SHIFT]], 0 -// CHECK-64BIT-LONG: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i64 [[VALUE]], i64 [[ROTATED]] -// CHECK-64BIT-LONG: ret i64 [[RESULT]] -// CHECK-64BIT-LONG } - unsigned __int64 test_rotr64(unsigned __int64 value, int shift) { return _rotr64(value, shift); } Index: cfe/trunk/test/CodeGen/pr27892.c =================================================================== --- cfe/trunk/test/CodeGen/pr27892.c +++ cfe/trunk/test/CodeGen/pr27892.c @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fms-extensions %s -emit-llvm -o - | FileCheck %s - -long test1(long *p) { - return _InterlockedIncrement(p); -} -// CHECK-DAG: define i64 @test1( -// CHECK: %[[p_addr:.*]] = alloca i64*, align 8 -// CHECK: store i64* %p, i64** %[[p_addr]], align 8 -// CHECK: %[[p_load:.*]] = load i64*, i64** %[[p_addr]], align 8 -// CHECK: %[[atomic_add:.*]] = atomicrmw add i64* %[[p_load]], i64 1 seq_cst -// CHECK: %[[res:.*]] = add i64 %[[atomic_add]], 1 -// CHECK: ret i64 %[[res]] - -long test2(long *p) { - return _InterlockedDecrement(p); -} -// CHECK-DAG: define i64 @test2( -// CHECK: %[[p_addr:.*]] = alloca i64*, align 8 -// CHECK: store i64* %p, i64** %[[p_addr]], align 8 -// CHECK: %[[p_load:.*]] = load i64*, i64** %[[p_addr]], align 8 -// CHECK: %[[atomic_sub:.*]] = atomicrmw sub i64* %[[p_load]], i64 1 seq_cst -// CHECK: %[[res:.*]] = sub i64 %[[atomic_sub]], 1 -// CHECK: ret i64 %[[res]]