Index: cfe/trunk/include/clang/Basic/Builtins.def =================================================================== --- cfe/trunk/include/clang/Basic/Builtins.def +++ cfe/trunk/include/clang/Basic/Builtins.def @@ -818,20 +818,23 @@ LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_interlockedbittestandset_rel, "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) -LANGBUILTIN(__popcnt64, "ULLiULLi", "nc", ALL_MS_LANGUAGES) +LANGBUILTIN(__lzcnt16, "UsUs", "nc", ALL_MS_LANGUAGES) +LANGBUILTIN(__lzcnt, "UiUi", "nc", ALL_MS_LANGUAGES) +LANGBUILTIN(__lzcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES) +LANGBUILTIN(__popcnt16, "UsUs", "nc", ALL_MS_LANGUAGES) +LANGBUILTIN(__popcnt, "UiUi", "nc", ALL_MS_LANGUAGES) +LANGBUILTIN(__popcnt64, "UWiUWi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl8, "UcUcUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl16, "UsUsUc", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_rotl, "UiUii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_lrotl, "UNiUNii", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotl64, "ULLiULLii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotl64, "UWiUWii", "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, "UNiUNii", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotr64, "ULLiULLii", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_rotr64, "UWiUWii", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES) Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp @@ -1802,6 +1802,21 @@ "cast"); return RValue::get(Result); } + case Builtin::BI__lzcnt16: + case Builtin::BI__lzcnt: + case Builtin::BI__lzcnt64: { + Value *ArgValue = EmitScalarExpr(E->getArg(0)); + + llvm::Type *ArgType = ArgValue->getType(); + Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); + + llvm::Type *ResultType = ConvertType(E->getType()); + Value *Result = Builder.CreateCall(F, {ArgValue, Builder.getFalse()}); + if (Result->getType() != ResultType) + Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, + "cast"); + return RValue::get(Result); + } case Builtin::BI__popcnt16: case Builtin::BI__popcnt: case Builtin::BI__popcnt64: Index: cfe/trunk/lib/Headers/intrin.h =================================================================== --- cfe/trunk/lib/Headers/intrin.h +++ cfe/trunk/lib/Headers/intrin.h @@ -90,8 +90,6 @@ void __lidt(void *); unsigned __int64 __ll_lshift(unsigned __int64, int); __int64 __ll_rshift(__int64, int); -unsigned int __lzcnt(unsigned int); -unsigned short __lzcnt16(unsigned short); static __inline__ void __movsb(unsigned char *, unsigned char const *, size_t); static __inline__ @@ -219,7 +217,6 @@ void __incgsdword(unsigned long); void __incgsqword(unsigned long); void __incgsword(unsigned long); -unsigned __int64 __lzcnt64(unsigned __int64); static __inline__ void __movsq(unsigned long long *, unsigned long long const *, size_t); static __inline__ Index: cfe/trunk/lib/Headers/lzcntintrin.h =================================================================== --- cfe/trunk/lib/Headers/lzcntintrin.h +++ cfe/trunk/lib/Headers/lzcntintrin.h @@ -31,6 +31,7 @@ /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lzcnt"))) +#ifndef _MSC_VER /// Counts the number of leading zero bits in the operand. /// /// \headerfile @@ -41,11 +42,8 @@ /// An unsigned 16-bit integer whose leading zeros are to be counted. /// \returns An unsigned 16-bit integer containing the number of leading zero /// bits in the operand. -static __inline__ unsigned short __DEFAULT_FN_ATTRS -__lzcnt16(unsigned short __X) -{ - return __builtin_ia32_lzcnt_u16(__X); -} +#define __lzcnt16(X) __builtin_ia32_lzcnt_u16((unsigned short)(X)) +#endif // _MSC_VER /// Counts the number of leading zero bits in the operand. /// @@ -82,6 +80,7 @@ } #ifdef __x86_64__ +#ifndef _MSC_VER /// Counts the number of leading zero bits in the operand. /// /// \headerfile @@ -93,11 +92,8 @@ /// \returns An unsigned 64-bit integer containing the number of leading zero /// bits in the operand. /// \see _lzcnt_u64 -static __inline__ unsigned long long __DEFAULT_FN_ATTRS -__lzcnt64(unsigned long long __X) -{ - return __builtin_ia32_lzcnt_u64(__X); -} +#define __lzcnt64(X) __builtin_ia32_lzcnt_u64((unsigned long long)(X)) +#endif // _MSC_VER /// Counts the number of leading zero bits in the operand. /// 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 @@ -148,3 +148,51 @@ // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1 // CHECK: ret i32 [[RESULT]] // CHECK: } + +unsigned short test__lzcnt16(unsigned short x) { + return __lzcnt16(x); +} +// CHECK: i16 @test__lzcnt16 +// CHECK: [[RESULT:%[0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false) +// CHECK: ret i16 [[RESULT]] +// CHECK: } + +unsigned int test__lzcnt(unsigned int x) { + return __lzcnt(x); +} +// CHECK: i32 @test__lzcnt +// CHECK: [[RESULT:%[0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false) +// CHECK: ret i32 [[RESULT]] +// CHECK: } + +unsigned __int64 test__lzcnt64(unsigned __int64 x) { + return __lzcnt64(x); +} +// CHECK: i64 @test__lzcnt64 +// CHECK: [[RESULT:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false) +// CHECK: ret i64 [[RESULT]] +// CHECK: } + +unsigned short test__popcnt16(unsigned short x) { + return __popcnt16(x); +} +// CHECK: i16 @test__popcnt16 +// CHECK: [[RESULT:%[0-9]+]] = tail call i16 @llvm.ctpop.i16(i16 %x) +// CHECK: ret i16 [[RESULT]] +// CHECK: } + +unsigned int test__popcnt(unsigned int x) { + return __popcnt(x); +} +// CHECK: i32 @test__popcnt +// CHECK: [[RESULT:%[0-9]+]] = tail call i32 @llvm.ctpop.i32(i32 %x) +// CHECK: ret i32 [[RESULT]] +// CHECK: } + +unsigned __int64 test__popcnt64(unsigned __int64 x) { + return __popcnt64(x); +} +// CHECK: i64 @test__popcnt64 +// CHECK: [[RESULT:%[0-9]+]] = tail call i64 @llvm.ctpop.i64(i64 %x) +// CHECK: ret i64 [[RESULT]] +// CHECK: }