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