[libc-commits] [libc] 1aab055 - [libc] Add CMake script to check host cpu features

Guillaume Chatelet via libc-commits libc-commits at lists.llvm.org
Thu Feb 27 00:53:31 PST 2020


Author: Guillaume Chatelet
Date: 2020-02-27T09:52:26+01:00
New Revision: 1aab055dd8ecd1ce8dcc0fe21da95e08b288b24e

URL: https://github.com/llvm/llvm-project/commit/1aab055dd8ecd1ce8dcc0fe21da95e08b288b24e
DIFF: https://github.com/llvm/llvm-project/commit/1aab055dd8ecd1ce8dcc0fe21da95e08b288b24e.diff

LOG: [libc] Add CMake script to check host cpu features

Summary:
Tested on MacOSX and Linux.
For robustness we can go the OpenCV way and add individual c++ files with intrinsics.
https://github.com/opencv/opencv/blob/master/cmake/checks/cpu_avx2.cpp

Reviewers: sivachandra, abrachet

Subscribers: mgorny, MaskRay, tschuett, libc-commits

Tags: #libc-project

Differential Revision: https://reviews.llvm.org/D74897

Added: 
    libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake
    libc/cmake/modules/cpu_features/check_avx.cpp
    libc/cmake/modules/cpu_features/check_avx512f.cpp
    libc/cmake/modules/cpu_features/check_sse.cpp
    libc/cmake/modules/cpu_features/check_sse2.cpp

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake
new file mode 100644
index 000000000000..adf81f3e38ab
--- /dev/null
+++ b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake
@@ -0,0 +1,99 @@
+#------------------------------------------------------------------------------
+# Cpu features definition and flags
+#
+# Declare a list of all supported cpu features in ALL_CPU_FEATURES.
+#
+# Declares associated flags to enable/disable individual feature of the form:
+# - CPU_FEATURE_<FEATURE>_ENABLE_FLAG
+# - CPU_FEATURE_<FEATURE>_DISABLE_FLAG
+#
+#------------------------------------------------------------------------------
+
+if(${LIBC_TARGET_MACHINE} MATCHES "x86|x86_64")
+  set(ALL_CPU_FEATURES SSE SSE2 AVX AVX512F)
+endif()
+
+function(_define_cpu_feature_flags feature)
+  if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
+    string(TOLOWER ${feature} lowercase_feature)
+    set(CPU_FEATURE_${feature}_ENABLE_FLAG "-m${lowercase_feature}" PARENT_SCOPE)
+    set(CPU_FEATURE_${feature}_DISABLE_FLAG "-mno-${lowercase_feature}" PARENT_SCOPE)
+  else()
+    # In future, we can extend for other compilers.
+    message(FATAL_ERROR "Unkown compiler ${CMAKE_CXX_COMPILER_ID}.")
+  endif()
+endfunction()
+
+# Defines cpu features flags
+foreach(feature IN LISTS ALL_CPU_FEATURES)
+  _define_cpu_feature_flags(${feature})
+endforeach()
+
+#------------------------------------------------------------------------------
+# Optimization level flags
+#
+# Generates the set of flags needed to compile for a up to a particular
+# optimization level.
+#
+# Creates variables of the form `CPU_FEATURE_OPT_<FEATURE>_FLAGS`.
+# CPU_FEATURE_OPT_NONE_FLAGS is a special flag for which no feature is needed.
+#
+# e.g.
+# CPU_FEATURE_OPT_NONE_FLAGS : -mno-sse;-mno-sse2;-mno-avx;-mno-avx512f
+# CPU_FEATURE_OPT_SSE_FLAGS : -msse;-mno-sse2;-mno-avx;-mno-avx512f
+# CPU_FEATURE_OPT_SSE2_FLAGS : -msse;-msse2;-mno-avx;-mno-avx512f
+# CPU_FEATURE_OPT_AVX_FLAGS : -msse;-msse2;-mavx;-mno-avx512f
+# CPU_FEATURE_OPT_AVX512F_FLAGS : -msse;-msse2;-mavx;-mavx512f
+#------------------------------------------------------------------------------
+
+# Helper function to concatenate flags needed to support optimization up to
+# a particular feature.
+function(_generate_flags_for_up_to feature flag_variable)
+  list(FIND ALL_CPU_FEATURES ${feature} feature_index)
+  foreach(current_feature IN LISTS ALL_CPU_FEATURES)
+    list(FIND ALL_CPU_FEATURES ${current_feature} current_feature_index)  
+    if(${current_feature_index} GREATER ${feature_index})
+      list(APPEND flags ${CPU_FEATURE_${current_feature}_DISABLE_FLAG})
+    else()
+      list(APPEND flags ${CPU_FEATURE_${current_feature}_ENABLE_FLAG})
+    endif()
+  endforeach()
+  set(${flag_variable} ${flags} PARENT_SCOPE)
+endfunction()
+
+function(_generate_opt_levels)
+  set(opt_levels NONE)
+  list(APPEND opt_levels ${ALL_CPU_FEATURES})
+  foreach(feature IN LISTS opt_levels)
+    set(flag_name "CPU_FEATURE_OPT_${feature}_FLAGS")
+    _generate_flags_for_up_to(${feature} ${flag_name})
+    set(${flag_name} ${${flag_name}} PARENT_SCOPE)
+  endforeach()
+endfunction()
+
+_generate_opt_levels()
+
+#------------------------------------------------------------------------------
+# Host cpu feature introspection
+#
+# Populates a HOST_CPU_FEATURES list containing the available CPU_FEATURE.
+#------------------------------------------------------------------------------
+function(_check_host_cpu_feature feature)
+  string(TOLOWER ${feature} lowercase_feature)
+  try_run(
+    run_result
+    compile_result
+    "${CMAKE_CURRENT_BINARY_DIR}/check_${lowercase_feature}"
+    "${CMAKE_MODULE_PATH}/cpu_features/check_${lowercase_feature}.cpp"
+    COMPILE_DEFINITIONS ${CPU_FEATURE_${feature}_ENABLE_FLAG}
+    OUTPUT_VARIABLE compile_output
+  )
+  if(${compile_result} AND ("${run_result}" EQUAL 0))
+    list(APPEND HOST_CPU_FEATURES ${feature})
+    set(HOST_CPU_FEATURES ${HOST_CPU_FEATURES} PARENT_SCOPE)
+  endif()
+endfunction()
+
+foreach(feature IN LISTS ALL_CPU_FEATURES)
+  _check_host_cpu_feature(${feature})
+endforeach()

diff  --git a/libc/cmake/modules/cpu_features/check_avx.cpp b/libc/cmake/modules/cpu_features/check_avx.cpp
new file mode 100644
index 000000000000..f0db3abab4e5
--- /dev/null
+++ b/libc/cmake/modules/cpu_features/check_avx.cpp
@@ -0,0 +1,8 @@
+#if !defined __AVX__
+#error "missing __AVX__"
+#endif
+#include <immintrin.h>
+int main() {
+  (void)_mm256_set1_epi8('0');
+  return 0;
+}

diff  --git a/libc/cmake/modules/cpu_features/check_avx512f.cpp b/libc/cmake/modules/cpu_features/check_avx512f.cpp
new file mode 100644
index 000000000000..93444e737ef4
--- /dev/null
+++ b/libc/cmake/modules/cpu_features/check_avx512f.cpp
@@ -0,0 +1,8 @@
+#if !defined __AVX512F__
+#error "missing __AVX512F__"
+#endif
+#include <immintrin.h>
+int main() {
+  (void)_mm512_undefined();
+  return 0;
+}

diff  --git a/libc/cmake/modules/cpu_features/check_sse.cpp b/libc/cmake/modules/cpu_features/check_sse.cpp
new file mode 100644
index 000000000000..1c1f67179fde
--- /dev/null
+++ b/libc/cmake/modules/cpu_features/check_sse.cpp
@@ -0,0 +1,8 @@
+#if !defined __SSE__
+#error "missing __SSE__"
+#endif
+#include <immintrin.h>
+int main() {
+  (void)_mm_set_ss(1.0f);
+  return 0;
+}

diff  --git a/libc/cmake/modules/cpu_features/check_sse2.cpp b/libc/cmake/modules/cpu_features/check_sse2.cpp
new file mode 100644
index 000000000000..f1e598de5877
--- /dev/null
+++ b/libc/cmake/modules/cpu_features/check_sse2.cpp
@@ -0,0 +1,8 @@
+#if !defined __SSE2__
+#error "missing __SSE2__"
+#endif
+#include <immintrin.h>
+int main() {
+  (void)_mm_set1_epi8('0');
+  return 0;
+}


        


More information about the libc-commits mailing list