r374516 - [X86] Always define the tzcnt intrinsics even when _MSC_VER is defined.

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 10 23:07:53 PDT 2019


Author: ctopper
Date: Thu Oct 10 23:07:53 2019
New Revision: 374516

URL: http://llvm.org/viewvc/llvm-project?rev=374516&view=rev
Log:
[X86] Always define the tzcnt intrinsics even when _MSC_VER is defined.

These intrinsics use llvm.cttz intrinsics so are always available
even without the bmi feature. We already don't check for the bmi
feature on the intrinsics themselves. But we were blocking the
include of the header file with _MSC_VER unless BMI was enabled
on the command line.

Fixes PR30506.

Modified:
    cfe/trunk/lib/Headers/bmiintrin.h
    cfe/trunk/lib/Headers/immintrin.h
    cfe/trunk/test/CodeGen/bmi-builtins.c

Modified: cfe/trunk/lib/Headers/bmiintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/bmiintrin.h?rev=374516&r1=374515&r2=374516&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/bmiintrin.h (original)
+++ cfe/trunk/lib/Headers/bmiintrin.h Thu Oct 10 23:07:53 2019
@@ -14,27 +14,13 @@
 #ifndef __BMIINTRIN_H
 #define __BMIINTRIN_H
 
-#define _tzcnt_u16(a)     (__tzcnt_u16((a)))
-
-#define _andn_u32(a, b)   (__andn_u32((a), (b)))
-
-/* _bextr_u32 != __bextr_u32 */
-#define _blsi_u32(a)      (__blsi_u32((a)))
-
-#define _blsmsk_u32(a)    (__blsmsk_u32((a)))
-
-#define _blsr_u32(a)      (__blsr_u32((a)))
-
-#define _tzcnt_u32(a)     (__tzcnt_u32((a)))
-
-/* Define the default attributes for the functions in this file. */
-#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi")))
-
 /* Allow using the tzcnt intrinsics even for non-BMI targets. Since the TZCNT
    instruction behaves as BSF on non-BMI targets, there is code that expects
    to use it as a potentially faster version of BSF. */
 #define __RELAXED_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
 
+#define _tzcnt_u16(a)     (__tzcnt_u16((a)))
+
 /// Counts the number of trailing zero bits in the operand.
 ///
 /// \headerfile <x86intrin.h>
@@ -51,6 +37,94 @@ __tzcnt_u16(unsigned short __X)
   return __builtin_ia32_tzcnt_u16(__X);
 }
 
+/// Counts the number of trailing zero bits in the operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
+///
+/// \param __X
+///    An unsigned 32-bit integer whose trailing zeros are to be counted.
+/// \returns An unsigned 32-bit integer containing the number of trailing zero
+///    bits in the operand.
+static __inline__ unsigned int __RELAXED_FN_ATTRS
+__tzcnt_u32(unsigned int __X)
+{
+  return __builtin_ia32_tzcnt_u32(__X);
+}
+
+/// Counts the number of trailing zero bits in the operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
+///
+/// \param __X
+///    An unsigned 32-bit integer whose trailing zeros are to be counted.
+/// \returns An 32-bit integer containing the number of trailing zero bits in
+///    the operand.
+static __inline__ int __RELAXED_FN_ATTRS
+_mm_tzcnt_32(unsigned int __X)
+{
+  return __builtin_ia32_tzcnt_u32(__X);
+}
+
+#define _tzcnt_u32(a)     (__tzcnt_u32((a)))
+
+#ifdef __x86_64__
+
+/// Counts the number of trailing zero bits in the operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
+///
+/// \param __X
+///    An unsigned 64-bit integer whose trailing zeros are to be counted.
+/// \returns An unsigned 64-bit integer containing the number of trailing zero
+///    bits in the operand.
+static __inline__ unsigned long long __RELAXED_FN_ATTRS
+__tzcnt_u64(unsigned long long __X)
+{
+  return __builtin_ia32_tzcnt_u64(__X);
+}
+
+/// Counts the number of trailing zero bits in the operand.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
+///
+/// \param __X
+///    An unsigned 64-bit integer whose trailing zeros are to be counted.
+/// \returns An 64-bit integer containing the number of trailing zero bits in
+///    the operand.
+static __inline__ long long __RELAXED_FN_ATTRS
+_mm_tzcnt_64(unsigned long long __X)
+{
+  return __builtin_ia32_tzcnt_u64(__X);
+}
+
+#define _tzcnt_u64(a)     (__tzcnt_u64((a)))
+
+#endif /* __x86_64__ */
+
+#undef __RELAXED_FN_ATTRS
+
+#if !defined(_MSC_VER) || __has_feature(modules) || defined(__BMI__)
+
+/* Define the default attributes for the functions in this file. */
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("bmi")))
+
+#define _andn_u32(a, b)   (__andn_u32((a), (b)))
+
+/* _bextr_u32 != __bextr_u32 */
+#define _blsi_u32(a)      (__blsi_u32((a)))
+
+#define _blsmsk_u32(a)    (__blsmsk_u32((a)))
+
+#define _blsr_u32(a)      (__blsr_u32((a)))
+
 /// Performs a bitwise AND of the second operand with the one's
 ///    complement of the first operand.
 ///
@@ -169,38 +243,6 @@ __blsr_u32(unsigned int __X)
   return __X & (__X - 1);
 }
 
-/// Counts the number of trailing zero bits in the operand.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
-///
-/// \param __X
-///    An unsigned 32-bit integer whose trailing zeros are to be counted.
-/// \returns An unsigned 32-bit integer containing the number of trailing zero
-///    bits in the operand.
-static __inline__ unsigned int __RELAXED_FN_ATTRS
-__tzcnt_u32(unsigned int __X)
-{
-  return __builtin_ia32_tzcnt_u32(__X);
-}
-
-/// Counts the number of trailing zero bits in the operand.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
-///
-/// \param __X
-///    An unsigned 32-bit integer whose trailing zeros are to be counted.
-/// \returns An 32-bit integer containing the number of trailing zero bits in
-///    the operand.
-static __inline__ int __RELAXED_FN_ATTRS
-_mm_tzcnt_32(unsigned int __X)
-{
-  return __builtin_ia32_tzcnt_u32(__X);
-}
-
 #ifdef __x86_64__
 
 #define _andn_u64(a, b)   (__andn_u64((a), (b)))
@@ -212,8 +254,6 @@ _mm_tzcnt_32(unsigned int __X)
 
 #define _blsr_u64(a)      (__blsr_u64((a)))
 
-#define _tzcnt_u64(a)     (__tzcnt_u64((a)))
-
 /// Performs a bitwise AND of the second operand with the one's
 ///    complement of the first operand.
 ///
@@ -332,41 +372,10 @@ __blsr_u64(unsigned long long __X)
   return __X & (__X - 1);
 }
 
-/// Counts the number of trailing zero bits in the operand.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
-///
-/// \param __X
-///    An unsigned 64-bit integer whose trailing zeros are to be counted.
-/// \returns An unsigned 64-bit integer containing the number of trailing zero
-///    bits in the operand.
-static __inline__ unsigned long long __RELAXED_FN_ATTRS
-__tzcnt_u64(unsigned long long __X)
-{
-  return __builtin_ia32_tzcnt_u64(__X);
-}
-
-/// Counts the number of trailing zero bits in the operand.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> TZCNT </c> instruction.
-///
-/// \param __X
-///    An unsigned 64-bit integer whose trailing zeros are to be counted.
-/// \returns An 64-bit integer containing the number of trailing zero bits in
-///    the operand.
-static __inline__ long long __RELAXED_FN_ATTRS
-_mm_tzcnt_64(unsigned long long __X)
-{
-  return __builtin_ia32_tzcnt_u64(__X);
-}
-
 #endif /* __x86_64__ */
 
 #undef __DEFAULT_FN_ATTRS
-#undef __RELAXED_FN_ATTRS
+
+#endif /* !defined(_MSC_VER) || __has_feature(modules) || defined(__BMI__) */
 
 #endif /* __BMIINTRIN_H */

Modified: cfe/trunk/lib/Headers/immintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/immintrin.h?rev=374516&r1=374515&r2=374516&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/immintrin.h (original)
+++ cfe/trunk/lib/Headers/immintrin.h Thu Oct 10 23:07:53 2019
@@ -64,9 +64,8 @@
 #include <vpclmulqdqintrin.h>
 #endif
 
-#if !defined(_MSC_VER) || __has_feature(modules) || defined(__BMI__)
+/* No feature check desired due to internal checks */
 #include <bmiintrin.h>
-#endif
 
 #if !defined(_MSC_VER) || __has_feature(modules) || defined(__BMI2__)
 #include <bmi2intrin.h>

Modified: cfe/trunk/test/CodeGen/bmi-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/bmi-builtins.c?rev=374516&r1=374515&r2=374516&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/bmi-builtins.c (original)
+++ cfe/trunk/test/CodeGen/bmi-builtins.c Thu Oct 10 23:07:53 2019
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - -Wall -Werror | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +bmi -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=CHECK,CHECK_TZCNT
+// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -emit-llvm -o - -Wall -Werror -DTEST_TZCNT | FileCheck %s --check-prefix=CHECK-TZCNT
 
 
 #include <immintrin.h>
@@ -13,12 +14,57 @@
 // instruction is identical in hardware, the AMD and Intel
 // intrinsics are different!
 
+unsigned short test_tzcnt_u16(unsigned short __X) {
+  // CHECK-TZCNT-LABEL: test_tzcnt_u16
+  // CHECK-TZCNT: i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
+  return _tzcnt_u16(__X);
+}
+
 unsigned short test__tzcnt_u16(unsigned short __X) {
-  // CHECK-LABEL: test__tzcnt_u16
-  // CHECK: i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
+  // CHECK-TZCNT-LABEL: test__tzcnt_u16
+  // CHECK-TZCNT: i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
   return __tzcnt_u16(__X);
 }
 
+unsigned int test__tzcnt_u32(unsigned int __X) {
+  // CHECK-TZCNT-LABEL: test__tzcnt_u32
+  // CHECK-TZCNT: i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+  return __tzcnt_u32(__X);
+}
+
+int test_mm_tzcnt_32(unsigned int __X) {
+  // CHECK-TZCNT-LABEL: test_mm_tzcnt_32
+  // CHECK-TZCNT: i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+  return _mm_tzcnt_32(__X);
+}
+
+unsigned int test_tzcnt_u32(unsigned int __X) {
+  // CHECK-TZCNT-LABEL: test_tzcnt_u32
+  // CHECK-TZCNT: i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
+  return _tzcnt_u32(__X);
+}
+
+#ifdef __x86_64__
+unsigned long long test__tzcnt_u64(unsigned long long __X) {
+  // CHECK-TZCNT-LABEL: test__tzcnt_u64
+  // CHECK-TZCNT: i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+  return __tzcnt_u64(__X);
+}
+
+long long test_mm_tzcnt_64(unsigned long long __X) {
+  // CHECK-TZCNT-LABEL: test_mm_tzcnt_64
+  // CHECK-TZCNT: i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+  return _mm_tzcnt_64(__X);
+}
+
+unsigned long long test_tzcnt_u64(unsigned long long __X) {
+  // CHECK-TZCNT-LABEL: test_tzcnt_u64
+  // CHECK-TZCNT: i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
+  return _tzcnt_u64(__X);
+}
+#endif
+
+#if !defined(TEST_TZCNT)
 unsigned int test__andn_u32(unsigned int __X, unsigned int __Y) {
   // CHECK-LABEL: test__andn_u32
   // CHECK: xor i32 %{{.*}}, -1
@@ -53,18 +99,6 @@ unsigned int test__blsr_u32(unsigned int
   return __blsr_u32(__X);
 }
 
-unsigned int test__tzcnt_u32(unsigned int __X) {
-  // CHECK-LABEL: test__tzcnt_u32
-  // CHECK: i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
-  return __tzcnt_u32(__X);
-}
-
-int test_mm_tzcnt_32(unsigned int __X) {
-  // CHECK-LABEL: test_mm_tzcnt_32
-  // CHECK: i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
-  return _mm_tzcnt_32(__X);
-}
-
 #ifdef __x86_64__
 unsigned long long test__andn_u64(unsigned long __X, unsigned long __Y) {
   // CHECK-LABEL: test__andn_u64
@@ -99,28 +133,10 @@ unsigned long long test__blsr_u64(unsign
   // CHECK: and i64 %{{.*}}, %{{.*}}
   return __blsr_u64(__X);
 }
-
-unsigned long long test__tzcnt_u64(unsigned long long __X) {
-  // CHECK-LABEL: test__tzcnt_u64
-  // CHECK: i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
-  return __tzcnt_u64(__X);
-}
-
-long long test_mm_tzcnt_64(unsigned long long __X) {
-  // CHECK-LABEL: test_mm_tzcnt_64
-  // CHECK: i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
-  return _mm_tzcnt_64(__X);
-}
 #endif
 
 // Intel intrinsics
 
-unsigned short test_tzcnt_u16(unsigned short __X) {
-  // CHECK-LABEL: test_tzcnt_u16
-  // CHECK: i16 @llvm.cttz.i16(i16 %{{.*}}, i1 false)
-  return _tzcnt_u16(__X);
-}
-
 unsigned int test_andn_u32(unsigned int __X, unsigned int __Y) {
   // CHECK-LABEL: test_andn_u32
   // CHECK: xor i32 %{{.*}}, -1
@@ -160,12 +176,6 @@ unsigned int test_blsr_u32(unsigned int
   return _blsr_u32(__X);
 }
 
-unsigned int test_tzcnt_u32(unsigned int __X) {
-  // CHECK-LABEL: test_tzcnt_u32
-  // CHECK: i32 @llvm.cttz.i32(i32 %{{.*}}, i1 false)
-  return _tzcnt_u32(__X);
-}
-
 #ifdef __x86_64__
 unsigned long long test_andn_u64(unsigned long __X, unsigned long __Y) {
   // CHECK-LABEL: test_andn_u64
@@ -206,10 +216,6 @@ unsigned long long test_blsr_u64(unsigne
   // CHECK: and i64 %{{.*}}, %{{.*}}
   return _blsr_u64(__X);
 }
-
-unsigned long long test_tzcnt_u64(unsigned long long __X) {
-  // CHECK-LABEL: test_tzcnt_u64
-  // CHECK: i64 @llvm.cttz.i64(i64 %{{.*}}, i1 false)
-  return _tzcnt_u64(__X);
-}
 #endif
+
+#endif // !defined(TEST_TZCNT)




More information about the cfe-commits mailing list