xref: /llvm-project/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake (revision e083a33478b2d570c89d7a9d9f05328b9232c072)
1# ------------------------------------------------------------------------------
2# Cpu features definition and flags
3# ------------------------------------------------------------------------------
4
5# Initialize ALL_CPU_FEATURES as empty list.
6set(ALL_CPU_FEATURES "")
7
8if(LIBC_TARGET_ARCHITECTURE_IS_X86_64)
9  set(ALL_CPU_FEATURES SSE2 SSE4_2 AVX AVX2 AVX512F AVX512BW FMA)
10  set(LIBC_COMPILE_OPTIONS_NATIVE -march=native)
11elseif(LIBC_TARGET_ARCHITECTURE_IS_AARCH64)
12  set(ALL_CPU_FEATURES "FullFP16")
13  set(LIBC_COMPILE_OPTIONS_NATIVE -mcpu=native)
14endif()
15
16if(LIBC_CROSSBUILD)
17  set(LIBC_COMPILE_OPTIONS_NATIVE ${LIBC_COMPILE_OPTIONS_DEFAULT})
18endif()
19
20# Making sure ALL_CPU_FEATURES is sorted.
21list(SORT ALL_CPU_FEATURES)
22
23# Function to check whether the target CPU supports the provided set of features.
24# Usage:
25# cpu_supports(
26#   <output variable>
27#   <list of cpu features>
28# )
29function(cpu_supports output_var features)
30  _intersection(var "${LIBC_CPU_FEATURES}" "${features}")
31  if("${var}" STREQUAL "${features}")
32    set(${output_var} TRUE PARENT_SCOPE)
33  else()
34    unset(${output_var} PARENT_SCOPE)
35  endif()
36endfunction()
37
38# ------------------------------------------------------------------------------
39# Internal helpers and utilities.
40# ------------------------------------------------------------------------------
41
42# Computes the intersection between two lists.
43function(_intersection output_var list1 list2)
44  foreach(element IN LISTS list1)
45    if("${list2}" MATCHES "(^|;)${element}(;|$)")
46      list(APPEND tmp "${element}")
47    endif()
48  endforeach()
49  set(${output_var} ${tmp} PARENT_SCOPE)
50endfunction()
51
52set(AVAILABLE_CPU_FEATURES "")
53if(LIBC_CROSSBUILD)
54  # If we are doing a cross build, we will just assume that all CPU features
55  # are available.
56  set(AVAILABLE_CPU_FEATURES ${ALL_CPU_FEATURES})
57else()
58  # Try compile a C file to check if flag is supported.
59  set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
60  foreach(feature IN LISTS ALL_CPU_FEATURES)
61    try_compile(
62      has_feature
63      ${CMAKE_CURRENT_BINARY_DIR}/cpu_features
64      SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_${feature}.cpp
65      COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${LIBC_COMPILE_OPTIONS_NATIVE}
66    )
67    if(has_feature)
68      list(APPEND AVAILABLE_CPU_FEATURES ${feature})
69    endif()
70  endforeach()
71endif()
72
73set(LIBC_CPU_FEATURES ${AVAILABLE_CPU_FEATURES} CACHE STRING "Host supported CPU features")
74
75_intersection(cpu_features "${AVAILABLE_CPU_FEATURES}" "${LIBC_CPU_FEATURES}")
76if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}")
77  message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}")
78else()
79  message(STATUS "Set CPU features: ${cpu_features}")
80endif()
81