• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ------------------------------------------------------------------------------
2# Compiler features definition and flags
3# ------------------------------------------------------------------------------
4
5set(
6  ALL_COMPILER_FEATURES
7    "builtin_ceil_floor_rint_trunc"
8    "builtin_fmax_fmin"
9    "builtin_fmaxf16_fminf16"
10    "builtin_round"
11    "builtin_roundeven"
12    "float16"
13    "float16_conversion"
14    "float128"
15    "fixed_point"
16)
17
18# Making sure ALL_COMPILER_FEATURES is sorted.
19list(SORT ALL_COMPILER_FEATURES)
20
21# Compiler features that are unavailable on GPU targets with the in-tree Clang.
22set(
23  CPU_ONLY_COMPILER_FEATURES
24    "float128"
25)
26
27# Function to check whether the compiler supports the provided set of features.
28# Usage:
29# compiler_supports(
30#   <output variable>
31#   <list of cpu features>
32# )
33function(compiler_supports output_var features)
34  _intersection(var "${LIBC_CPU_FEATURES}" "${features}")
35  if("${var}" STREQUAL "${features}")
36    set(${output_var} TRUE PARENT_SCOPE)
37  else()
38    unset(${output_var} PARENT_SCOPE)
39  endif()
40endfunction()
41
42# ------------------------------------------------------------------------------
43# Internal helpers and utilities.
44# ------------------------------------------------------------------------------
45
46# Computes the intersection between two lists.
47function(_intersection output_var list1 list2)
48  foreach(element IN LISTS list1)
49    if("${list2}" MATCHES "(^|;)${element}(;|$)")
50      list(APPEND tmp "${element}")
51    endif()
52  endforeach()
53  set(${output_var} ${tmp} PARENT_SCOPE)
54endfunction()
55
56set(AVAILABLE_COMPILER_FEATURES "")
57
58# Try compile a C file to check if flag is supported.
59foreach(feature IN LISTS ALL_COMPILER_FEATURES)
60  set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
61  set(compile_options ${LIBC_COMPILE_OPTIONS_NATIVE})
62  set(link_options "")
63  if(${feature} STREQUAL "fixed_point")
64    list(APPEND compile_options "-ffixed-point")
65  elseif(${feature} MATCHES "^builtin_" OR
66         ${feature} STREQUAL "float16_conversion")
67    set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
68    set(link_options -nostdlib)
69    # The compiler might handle calls to math builtins by generating calls to
70    # the respective libc math functions, in which case we cannot use these
71    # builtins in our implementations of these functions. We check that this is
72    # not the case by trying to link an executable, since linking would fail due
73    # to unresolved references with -nostdlib if calls to libc functions were
74    # generated.
75    #
76    # We also had issues with soft-float float16 conversion functions using both
77    # compiler-rt and libgcc, so we also check whether we can convert from and
78    # to float16 without calls to compiler runtime functions by trying to link
79    # an executable with -nostdlib.
80    set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
81  endif()
82
83  if(LIBC_TARGET_OS_IS_GPU)
84    # CUDA shouldn't be required to build the libc, only to test it, so we can't
85    # try to build CUDA binaries here. Since GPU builds are always compiled with
86    # the in-tree Clang, we just hardcode which compiler features are available
87    # when targeting GPUs.
88    if(feature IN_LIST CPU_ONLY_COMPILER_FEATURES)
89      set(has_feature FALSE)
90    else()
91      set(has_feature TRUE)
92    endif()
93  else()
94    try_compile(
95      has_feature
96      ${CMAKE_CURRENT_BINARY_DIR}/compiler_features
97      SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/compiler_features/check_${feature}.cpp
98      COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${compile_options}
99      LINK_OPTIONS ${link_options}
100    )
101  endif()
102
103  if(has_feature)
104    list(APPEND AVAILABLE_COMPILER_FEATURES ${feature})
105    if(${feature} STREQUAL "float16")
106      set(LIBC_TYPES_HAS_FLOAT16 TRUE)
107    elseif(${feature} STREQUAL "float16_conversion")
108      add_compile_definitions(__LIBC_USE_FLOAT16_CONVERSION)
109    elseif(${feature} STREQUAL "float128")
110      set(LIBC_TYPES_HAS_FLOAT128 TRUE)
111    elseif(${feature} STREQUAL "fixed_point")
112      set(LIBC_COMPILER_HAS_FIXED_POINT TRUE)
113    elseif(${feature} STREQUAL "builtin_ceil_floor_rint_trunc")
114      set(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_RINT_TRUNC TRUE)
115    elseif(${feature} STREQUAL "builtin_fmax_fmin")
116      set(LIBC_COMPILER_HAS_BUILTIN_FMAX_FMIN TRUE)
117    elseif(${feature} STREQUAL "builtin_fmaxf16_fminf16")
118      set(LIBC_COMPILER_HAS_BUILTIN_FMAXF16_FMINF16 TRUE)
119    elseif(${feature} STREQUAL "builtin_round")
120      set(LIBC_COMPILER_HAS_BUILTIN_ROUND TRUE)
121    elseif(${feature} STREQUAL "builtin_roundeven")
122      set(LIBC_COMPILER_HAS_BUILTIN_ROUNDEVEN TRUE)
123    endif()
124  endif()
125endforeach()
126
127set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
128set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
129set(link_options "")
130
131message(STATUS "Compiler features available: ${AVAILABLE_COMPILER_FEATURES}")
132
133### Compiler Feature Detection ###
134
135# clang-8+, gcc-12+
136check_cxx_compiler_flag("-ftrivial-auto-var-init=pattern" LIBC_CC_SUPPORTS_PATTERN_INIT)
137
138# clang-6+, gcc-13+
139check_cxx_compiler_flag("-nostdlib++" LIBC_CC_SUPPORTS_NOSTDLIBPP)
140
141# clang-3.0+
142check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)
143