2017-01-27 19:55:33 +00:00
# https://software.intel.com/sites/landingpage/IntrinsicsGuide/
include ( CheckCXXSourceCompiles )
2017-07-17 14:21:43 +00:00
include ( CMakePushCheckState )
cmake_push_check_state ( )
2017-01-27 19:55:33 +00:00
2021-08-09 23:58:51 +00:00
# The variables HAVE_* determine if compiler has support for the flag to use the corresponding instruction set.
# The options ENABLE_* determine if we will tell compiler to actually use the corresponding instruction set if compiler can do it.
# All of them are unrelated to the instruction set at the host machine
# (you can compile for newer instruction set on old machines and vice versa).
option ( ENABLE_SSSE3 "Use SSSE3 instructions on x86_64" 1 )
option ( ENABLE_SSE41 "Use SSE4.1 instructions on x86_64" 1 )
option ( ENABLE_SSE42 "Use SSE4.2 instructions on x86_64" 1 )
option ( ENABLE_PCLMULQDQ "Use pclmulqdq instructions on x86_64" 1 )
option ( ENABLE_POPCNT "Use popcnt instructions on x86_64" 1 )
2021-10-13 02:04:21 +00:00
option ( ENABLE_AVX "Use AVX instructions on x86_64" 0 )
option ( ENABLE_AVX2 "Use AVX2 instructions on x86_64" 0 )
2021-10-12 23:43:34 +00:00
option ( ENABLE_AVX512 "Use AVX512 instructions on x86_64" 0 )
2021-10-13 02:04:21 +00:00
option ( ENABLE_BMI "Use BMI instructions on x86_64" 0 )
option ( ENABLE_AVX2_FOR_SPEC_OP "Use avx2 instructions for specific operations on x86_64" 0 )
option ( ENABLE_AVX512_FOR_SPEC_OP "Use avx512 instructions for specific operations on x86_64" 0 )
2021-08-09 23:58:51 +00:00
option ( ARCH_NATIVE "Add -march=native compiler flag. This makes your binaries non-portable but more performant code may be generated. This option overrides ENABLE_* options for specific instruction set. Highly not recommended to use." 0 )
if ( ARCH_NATIVE )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} -march=native" )
2021-11-21 11:30:04 +00:00
elseif ( ARCH_AARCH64 )
2021-11-21 11:30:36 +00:00
set ( COMPILER_FLAGS "${COMPILER_FLAGS} -march=armv8-a+crc" )
2021-11-21 11:30:04 +00:00
2021-08-09 23:58:51 +00:00
else ( )
set ( TEST_FLAG "-mssse3" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <tmmintrin.h>
i n t main ( ) {
_ _ m 6 4 a = _mm_abs_pi8 ( __m64( ) ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ S S S E 3 )
if ( HAVE_SSSE3 AND ENABLE_SSSE3 )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
set ( TEST_FLAG "-msse4.1" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <smmintrin.h>
i n t main ( ) {
a u t o a = _mm_insert_epi8 ( __m128i( ) , 0 , 0 ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ S S E 4 1 )
if ( HAVE_SSE41 AND ENABLE_SSE41 )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
if ( ARCH_PPC64LE )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} -maltivec -D__SSE2__=1 -DNO_WARN_X86_INTRINSICS" )
endif ( )
set ( TEST_FLAG "-msse4.2" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <nmmintrin.h>
i n t main ( ) {
a u t o a = _mm_crc32_u64 ( 0, 0 ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ S S E 4 2 )
if ( HAVE_SSE42 AND ENABLE_SSE42 )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
set ( TEST_FLAG "-mpclmul" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <wmmintrin.h>
i n t main ( ) {
a u t o a = _mm_clmulepi64_si128 ( __m128i( ) , __m128i ( ) , 0 ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ P C L M U L Q D Q )
if ( HAVE_PCLMULQDQ AND ENABLE_PCLMULQDQ )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
set ( TEST_FLAG "-mpopcnt" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
i n t main ( ) {
a u t o a = __builtin_popcountll ( 0 ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ P O P C N T )
if ( HAVE_POPCNT AND ENABLE_POPCNT )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
set ( TEST_FLAG "-mavx" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <immintrin.h>
i n t main ( ) {
a u t o a = _mm256_insert_epi8 ( __m256i( ) , 0 , 0 ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ A V X )
if ( HAVE_AVX AND ENABLE_AVX )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
set ( TEST_FLAG "-mavx2" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <immintrin.h>
i n t main ( ) {
a u t o a = _mm256_add_epi16 ( __m256i( ) , __m256i ( ) ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ A V X 2 )
if ( HAVE_AVX2 AND ENABLE_AVX2 )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
2021-10-12 23:43:34 +00:00
set ( TEST_FLAG "-mavx512f -mavx512bw" )
2021-10-11 17:21:13 +00:00
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <immintrin.h>
i n t main ( ) {
a u t o a = _mm512_setzero_epi32 ( ) ;
2021-11-21 11:30:04 +00:00
( v o i d ) a ;
2021-10-11 17:21:13 +00:00
a u t o b = _mm512_add_epi16 ( __m512i( ) , __m512i ( ) ) ;
( v o i d ) b ;
r e t u r n 0 ;
}
" H A V E _ A V X 5 1 2 )
if ( HAVE_AVX512 AND ENABLE_AVX512 )
2021-10-12 23:43:34 +00:00
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
2021-10-11 17:21:13 +00:00
endif ( )
2022-01-17 04:03:12 +00:00
set ( TEST_FLAG "-mavx512bw -mavx512vl" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <immintrin.h>
i n t main ( ) {
a u t o m a s k = _mm_cmp_epi8_mask ( __m128i( ) , __m128i ( ) , 0 ) ;
( v o i d ) m a s k ;
r e t u r n 0 ;
}
" H A V E _ A V X 5 1 2 _ B W _ V L )
if ( HAVE_AVX512_BW_VL AND ENABLE_AVX512 )
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
endif ( )
2021-10-11 17:21:13 +00:00
set ( TEST_FLAG "-mbmi" )
set ( CMAKE_REQUIRED_FLAGS "${TEST_FLAG} -O0" )
check_cxx_source_compiles ( "
#include <immintrin.h>
i n t main ( ) {
a u t o a = _blsr_u32 ( 0 ) ;
( v o i d ) a ;
r e t u r n 0 ;
}
" H A V E _ B M I )
if ( HAVE_BMI AND ENABLE_BMI )
2021-10-12 23:43:34 +00:00
set ( COMPILER_FLAGS "${COMPILER_FLAGS} ${TEST_FLAG}" )
2021-11-21 11:30:04 +00:00
endif ( )
2021-10-12 23:43:34 +00:00
2021-11-21 11:30:04 +00:00
# Limit avx2/avx512 flag for specific source build
2021-10-13 17:19:21 +00:00
set ( X86_INTRINSICS_FLAGS "" )
2021-10-13 02:04:21 +00:00
if ( ENABLE_AVX2_FOR_SPEC_OP )
if ( HAVE_BMI )
set ( X86_INTRINSICS_FLAGS "${X86_INTRINSICS_FLAGS} -mbmi" )
endif ( )
if ( HAVE_AVX AND HAVE_AVX2 )
set ( X86_INTRINSICS_FLAGS "${X86_INTRINSICS_FLAGS} -mavx -mavx2" )
endif ( )
endif ( )
if ( ENABLE_AVX512_FOR_SPEC_OP )
set ( X86_INTRINSICS_FLAGS "" )
if ( HAVE_BMI )
set ( X86_INTRINSICS_FLAGS "${X86_INTRINSICS_FLAGS} -mbmi" )
endif ( )
if ( HAVE_AVX512 )
2021-10-26 23:49:15 +00:00
set ( X86_INTRINSICS_FLAGS "${X86_INTRINSICS_FLAGS} -mavx512f -mavx512bw -mprefer-vector-width=256" )
2021-10-13 02:04:21 +00:00
endif ( )
2022-01-17 04:03:12 +00:00
if ( HAVE_AVX512_BW_VL )
set ( X86_INTRINSICS_FLAGS "${X86_INTRINSICS_FLAGS} -mavx512bw -mavx512vl" )
endif ( )
2021-10-13 02:04:21 +00:00
endif ( )
2017-01-27 19:55:33 +00:00
endif ( )
2017-07-17 14:21:43 +00:00
cmake_pop_check_state ( )