diff --git a/src/bitops.c b/src/bitops.c index 803199e14..2222c05ea 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -16,12 +16,12 @@ /* Count number of bits set in the binary array pointed by 's' and long * 'count' bytes. The implementation of this function is required to * work with an input string length up to 512 MB or more (server.proto_max_bulk_len) */ -__attribute__((target("popcnt"))) +ATTRIBUTE_TARGET_POPCNT long long redisPopcount(void *s, long count) { long long bits = 0; unsigned char *p = s; uint32_t *p4; -#if defined(__x86_64__) && ((defined(__GNUC__) && __GNUC__ > 5) || (defined(__clang__))) +#if defined(HAVE_POPCNT) int use_popcnt = __builtin_cpu_supports("popcnt"); /* Check if CPU supports POPCNT instruction. */ #else int use_popcnt = 0; /* Assume CPU does not support POPCNT if diff --git a/src/config.h b/src/config.h index 6910951f8..ae072c9df 100644 --- a/src/config.h +++ b/src/config.h @@ -307,4 +307,15 @@ void setcpuaffinity(const char *cpulist); #define HAVE_FADVISE #endif +#if defined(__x86_64__) && ((defined(__GNUC__) && __GNUC__ > 5) || (defined(__clang__))) + #if defined(__has_attribute) && __has_attribute(target) + #define HAVE_POPCNT + #define ATTRIBUTE_TARGET_POPCNT __attribute__((target("popcnt"))) + #else + #define ATTRIBUTE_TARGET_POPCNT + #endif +#else + #define ATTRIBUTE_TARGET_POPCNT +#endif + #endif