Fix compilation with clang 3.7

This commit is contained in:
Eric Biggers 2016-11-04 20:38:09 -07:00
parent 2ea8ddae66
commit 3a3d2da7c2
4 changed files with 49 additions and 36 deletions

View File

@ -121,22 +121,21 @@ typedef size_t machine_word_t;
# define COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE 0
#endif
/* Does the compiler support __attribute__((target("pclmul")))? */
/* Are target-specific intrinsics supported in 'target' attribute functions? */
#ifndef COMPILER_SUPPORTS_TARGET_INTRINSICS
# define COMPILER_SUPPORTS_TARGET_INTRINSICS 0
#endif
/* Which targets are supported with the 'target' function attribute? */
#ifndef COMPILER_SUPPORTS_PCLMUL_TARGET
# define COMPILER_SUPPORTS_PCLMUL_TARGET 0
#endif
/* Does the compiler support __attribute__((target("bmi2")))? */
#ifndef COMPILER_SUPPORTS_BMI2_TARGET
# define COMPILER_SUPPORTS_BMI2_TARGET 0
#endif
/* Does the compiler support __attribute__((target("avx")))? */
#ifndef COMPILER_SUPPORTS_AVX_TARGET
# define COMPILER_SUPPORTS_AVX_TARGET 0
#endif
/* Does the compiler support __attribute__((target("avx2")))? */
#ifndef COMPILER_SUPPORTS_AVX2_TARGET
# define COMPILER_SUPPORTS_AVX2_TARGET 0
#endif

View File

@ -7,6 +7,21 @@
(__GNUC__ > (major) || \
(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
/* Note: only check the clang version when absolutely necessary!
* "Vendors" such as Apple can use different version numbers. */
#ifdef __clang__
# ifdef __apple_build_version__
# define CLANG_PREREQ(major, minor, apple_version) \
(__apple_build_version__ >= (apple_version))
# else
# define CLANG_PREREQ(major, minor, apple_version) \
(__clang_major__ > (major) || \
(__clang_major__ == (major) && __clang_minor__ >= (minor)))
# endif
#else
# define CLANG_PREREQ(major, minor, apple_version) 0
#endif
#ifndef __has_attribute
# define __has_attribute(attribute) 0
#endif
@ -32,42 +47,39 @@
#define prefetchw(addr) __builtin_prefetch((addr), 1)
#define _aligned_attribute(n) __attribute__((aligned(n)))
#define COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE \
(GCC_PREREQ(4, 4) || __has_attribute(target))
/*
* Support for the following instruction set extensions was introduced by the
* following gcc versions:
* Support for the following x86 instruction set extensions was introduced by
* the following gcc versions:
*
* PCLMUL 4.4
* AVX 4.6
* BMI2 4.7
* AVX2 4.7
*
* However, target-specific intrinsics don't work in __attribute__((target(..)))
* functions until gcc 4.9. Currently we need this for PCLMUL and AVX2 but not
* AVX and BMI2. Hence the particular version checks below.
* With clang, __has_builtin() can be used to detect the presence of one of the
* associated builtins.
*
* Note: clang does not have this problem and also supports __has_builtin() for
* testing for whether an intrinsic is available without having to check the
* compiler version.
* Additionally, gcc 4.4 introduced the 'target' function attribute. With
* clang, support for this can be detected with with __has_attribute(target).
*
* However, prior to gcc 4.9 and clang 3.8, x86 intrinsics not available in the
* main target could not be used in 'target' attribute functions. Unfortunately
* clang has no feature test macro for this so we have to check its version.
*/
#define COMPILER_SUPPORTS_PCLMUL_TARGET \
(COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE && \
(GCC_PREREQ(4, 9) || __has_builtin(__builtin_ia32_pclmulqdq128)))
#define COMPILER_SUPPORTS_AVX_TARGET \
(COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE && \
(GCC_PREREQ(4, 6) || __has_builtin(__builtin_ia32_maxps256)))
#define COMPILER_SUPPORTS_BMI2_TARGET \
(COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE && \
(GCC_PREREQ(4, 7) || __has_builtin(__builtin_ia32_pdep_di)))
#define COMPILER_SUPPORTS_AVX2_TARGET \
(COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE && \
(GCC_PREREQ(4, 9) || __has_builtin(__builtin_ia32_pmaddwd256)))
#define COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE \
(GCC_PREREQ(4, 4) || __has_attribute(target))
#if COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE
# define COMPILER_SUPPORTS_TARGET_INTRINSICS \
(GCC_PREREQ(4, 9) || CLANG_PREREQ(3, 8, 7030000))
# define COMPILER_SUPPORTS_PCLMUL_TARGET \
(GCC_PREREQ(4, 4) || __has_builtin(__builtin_ia32_pclmulqdq128))
# define COMPILER_SUPPORTS_AVX_TARGET \
(GCC_PREREQ(4, 6) || __has_builtin(__builtin_ia32_maxps256))
# define COMPILER_SUPPORTS_BMI2_TARGET \
(GCC_PREREQ(4, 7) || __has_builtin(__builtin_ia32_pdep_di))
# define COMPILER_SUPPORTS_AVX2_TARGET \
(GCC_PREREQ(4, 7) || __has_builtin(__builtin_ia32_pmaddwd256))
#endif
/* Newer gcc supports __BYTE_ORDER__. Older gcc doesn't. */
#ifdef __BYTE_ORDER__

View File

@ -74,7 +74,8 @@
/* Include the AVX2 implementation? */
#define NEED_AVX2_IMPL 0
#if defined(__AVX2__) || \
(X86_CPU_FEATURES_ENABLED && COMPILER_SUPPORTS_AVX2_TARGET)
(X86_CPU_FEATURES_ENABLED && COMPILER_SUPPORTS_AVX2_TARGET && \
COMPILER_SUPPORTS_TARGET_INTRINSICS)
# include <immintrin.h>
# undef NEED_AVX2_IMPL
# define NEED_AVX2_IMPL 1

View File

@ -183,7 +183,8 @@
/* Include the PCLMUL implementation? */
#define NEED_PCLMUL_IMPL 0
#if defined(__PCLMUL__) || \
(X86_CPU_FEATURES_ENABLED && COMPILER_SUPPORTS_PCLMUL_TARGET)
(X86_CPU_FEATURES_ENABLED && COMPILER_SUPPORTS_PCLMUL_TARGET && \
COMPILER_SUPPORTS_TARGET_INTRINSICS)
# include <wmmintrin.h>
# undef NEED_PCLMUL_IMPL
# define NEED_PCLMUL_IMPL 1