Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ 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: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ 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: lib/Headers/intrin.h =================================================================== --- lib/Headers/intrin.h +++ 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: lib/Headers/lzcntintrin.h =================================================================== --- lib/Headers/lzcntintrin.h +++ lib/Headers/lzcntintrin.h @@ -38,39 +38,6 @@ /// This intrinsic corresponds to the \c LZCNT instruction. /// /// \param __X -/// 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); -} - -/// Counts the number of leading zero bits in the operand. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c LZCNT instruction. -/// -/// \param __X -/// An unsigned 32-bit integer whose leading zeros are to be counted. -/// \returns An unsigned 32-bit integer containing the number of leading zero -/// bits in the operand. -/// \see _lzcnt_u32 -static __inline__ unsigned int __DEFAULT_FN_ATTRS -__lzcnt32(unsigned int __X) -{ - return __builtin_ia32_lzcnt_u32(__X); -} - -/// Counts the number of leading zero bits in the operand. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c LZCNT instruction. -/// -/// \param __X /// An unsigned 32-bit integer whose leading zeros are to be counted. /// \returns An unsigned 32-bit integer containing the number of leading zero /// bits in the operand. @@ -92,23 +59,6 @@ /// An unsigned 64-bit integer whose leading zeros are to be counted. /// \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); -} - -/// Counts the number of leading zero bits in the operand. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the \c LZCNT instruction. -/// -/// \param __X -/// An unsigned 64-bit integer whose leading zeros are to be counted. -/// \returns An unsigned 64-bit integer containing the number of leading zero -/// bits in the operand. /// \see __lzcnt64 static __inline__ unsigned long long __DEFAULT_FN_ATTRS _lzcnt_u64(unsigned long long __X) Index: test/CodeGen/lzcnt-builtins.c =================================================================== --- test/CodeGen/lzcnt-builtins.c +++ test/CodeGen/lzcnt-builtins.c @@ -3,24 +3,6 @@ #include -unsigned short test__lzcnt16(unsigned short __X) -{ - // CHECK: @llvm.ctlz.i16(i16 %{{.*}}, i1 false) - return __lzcnt16(__X); -} - -unsigned int test_lzcnt32(unsigned int __X) -{ - // CHECK: @llvm.ctlz.i32(i32 %{{.*}}, i1 false) - return __lzcnt32(__X); -} - -unsigned long long test__lzcnt64(unsigned long long __X) -{ - // CHECK: @llvm.ctlz.i64(i64 %{{.*}}, i1 false) - return __lzcnt64(__X); -} - unsigned int test_lzcnt_u32(unsigned int __X) { // CHECK: @llvm.ctlz.i32(i32 %{{.*}}, i1 false) Index: test/CodeGen/ms-intrinsics-other.c =================================================================== --- test/CodeGen/ms-intrinsics-other.c +++ 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: } Index: test/Headers/x86intrin-2.c =================================================================== --- test/Headers/x86intrin-2.c +++ test/Headers/x86intrin-2.c @@ -56,10 +56,6 @@ return _bzhi_u32(x, y); } -unsigned short __attribute__((__target__("lzcnt"))) lzcnt16_wrap(unsigned short x) { - return __lzcnt16(x); -} - __m256d __attribute__((__target__("fma"))) mm256_fmsubadd_pd_wrap(__m256d a, __m256d b, __m256d c) { return _mm256_fmsubadd_pd(a, b, c); }