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