craig.topper created this revision.
craig.topper added reviewers: RKSimon, spatel, andreadb.

gcc and icc both implement __popcntd and __popcntq which we did not. gcc 
doesn't seem to require a feature flag for the _popcnt32/_popcnt64 spelling and 
will use a libcall if its not supported.


https://reviews.llvm.org/D59567

Files:
  clang/lib/Headers/ia32intrin.h
  clang/lib/Headers/popcntintrin.h
  clang/test/CodeGen/popcnt-builtins.c

Index: clang/test/CodeGen/popcnt-builtins.c
===================================================================
--- clang/test/CodeGen/popcnt-builtins.c
+++ clang/test/CodeGen/popcnt-builtins.c
@@ -1,24 +1,39 @@
-// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +popcnt -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,CHECK-POPCNT
+// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
 
 
-#include <immintrin.h>
+#include <x86intrin.h>
 
-unsigned int test_mm_popcnt_u32(unsigned int __X) {
-  //CHECK: call i32 @llvm.ctpop.i32
+#ifdef __POPCNT__
+int test_mm_popcnt_u32(unsigned int __X) {
+  //CHECK-POPCNT: call i32 @llvm.ctpop.i32
   return _mm_popcnt_u32(__X);
 }
+#endif
 
-unsigned int test_popcnt_32(int __X) {
+int test_popcnt32(unsigned int __X) {
   //CHECK: call i32 @llvm.ctpop.i32
   return _popcnt32(__X);
 }
 
-unsigned long long test_mm_popcnt_u64(unsigned long long __X) {
-  //CHECK: call i64 @llvm.ctpop.i64
+int test__popcntd(unsigned int __X) {
+  //CHECK: call i32 @llvm.ctpop.i32
+  return __popcntd(__X);
+}
+
+#ifdef __POPCNT__
+long long test_mm_popcnt_u64(unsigned long long __X) {
+  //CHECK-POPCNT: call i64 @llvm.ctpop.i64
   return _mm_popcnt_u64(__X);
 }
+#endif
 
-unsigned long long test_popcnt_64(long long __X) {
+long long test_popcnt64(unsigned long long __X) {
   //CHECK: call i64 @llvm.ctpop.i64
   return _popcnt64(__X);
 }
+
+long long test__popcntq(unsigned long long __X) {
+  //CHECK: call i64 @llvm.ctpop.i64
+  return __popcntq(__X);
+}
Index: clang/lib/Headers/popcntintrin.h
===================================================================
--- clang/lib/Headers/popcntintrin.h
+++ clang/lib/Headers/popcntintrin.h
@@ -43,22 +43,6 @@
   return __builtin_popcount(__A);
 }
 
-/// Counts the number of bits in the source operand having a value of 1.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
-///
-/// \param __A
-///    A signed 32-bit integer operand.
-/// \returns A 32-bit integer containing the number of bits with value 1 in the
-///    source operand.
-static __inline__ int __DEFAULT_FN_ATTRS
-_popcnt32(int __A)
-{
-  return __builtin_popcount(__A);
-}
-
 #ifdef __x86_64__
 /// Counts the number of bits in the source operand having a value of 1.
 ///
@@ -75,22 +59,6 @@
 {
   return __builtin_popcountll(__A);
 }
-
-/// Counts the number of bits in the source operand having a value of 1.
-///
-/// \headerfile <x86intrin.h>
-///
-/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
-///
-/// \param __A
-///    A signed 64-bit integer operand.
-/// \returns A 64-bit integer containing the number of bits with value 1 in the
-///    source operand.
-static __inline__ long long __DEFAULT_FN_ATTRS
-_popcnt64(long long __A)
-{
-  return __builtin_popcountll(__A);
-}
 #endif /* __x86_64__ */
 
 #undef __DEFAULT_FN_ATTRS
Index: clang/lib/Headers/ia32intrin.h
===================================================================
--- clang/lib/Headers/ia32intrin.h
+++ clang/lib/Headers/ia32intrin.h
@@ -28,6 +28,44 @@
 #ifndef __IA32INTRIN_H
 #define __IA32INTRIN_H
 
+/// Counts the number of bits in the source operand having a value of 1.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
+///
+/// \param __A
+///    An unsigned 32-bit integer operand.
+/// \returns A 32-bit integer containing the number of bits with value 1 in the
+///    source operand.
+static __inline__ int __attribute__((__always_inline__, __nodebug__))
+__popcntd(unsigned int __A)
+{
+  return __builtin_popcount(__A);
+}
+
+#define _popcnt32(A) __popcntd((A))
+
+#ifdef __x86_64__
+/// Counts the number of bits in the source operand having a value of 1.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the <c> POPCNT </c> instruction.
+///
+/// \param __A
+///    An unsigned 64-bit integer operand.
+/// \returns A 64-bit integer containing the number of bits with value 1 in the
+///    source operand.
+static __inline__ long long __attribute__((__always_inline__, __nodebug__))
+__popcntq(unsigned long long __A)
+{
+  return __builtin_popcountll(__A);
+}
+
+#define _popcnt64(A) __popcntq((A))
+#endif /* __x86_64__ */
+
 #ifdef __x86_64__
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __readeflags(void)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to