diff --git a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake index 9a18ac018d77f..b97b03f7b07a8 100644 --- a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake +++ b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake @@ -44,32 +44,44 @@ function(_intersection output_var list1 list2) set(${output_var} ${tmp} PARENT_SCOPE) endfunction() -set(AVAILABLE_CPU_FEATURES "") -if(LIBC_CROSSBUILD) - # If we are doing a cross build, we will just assume that all CPU features - # are available. - set(AVAILABLE_CPU_FEATURES ${ALL_CPU_FEATURES}) -else() - # Try compile a C file to check if flag is supported. - set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +# Generates a cpp file to introspect the compiler defined flags. +function(_generate_check_code) foreach(feature IN LISTS ALL_CPU_FEATURES) - try_compile( - has_feature - ${CMAKE_CURRENT_BINARY_DIR}/cpu_features - SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_${feature}.cpp - COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${LIBC_COMPILE_OPTIONS_NATIVE} - ) - if(has_feature) - list(APPEND AVAILABLE_CPU_FEATURES ${feature}) - endif() + set(DEFINITIONS + "${DEFINITIONS} +#ifdef __${feature}__ + \"${feature}\", +#endif") endforeach() -endif() + configure_file( + "${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_cpu_features.cpp.in" + "cpu_features/check_cpu_features.cpp" @ONLY) +endfunction() +_generate_check_code() -set(LIBC_CPU_FEATURES ${AVAILABLE_CPU_FEATURES} CACHE STRING "Host supported CPU features") +set(LIBC_CPU_FEATURES "" CACHE PATH "Host supported CPU features") -_intersection(cpu_features "${AVAILABLE_CPU_FEATURES}" "${LIBC_CPU_FEATURES}") -if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}") - message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}") -else() +if(LIBC_CROSSBUILD) + _intersection(cpu_features "${ALL_CPU_FEATURES}" "${LIBC_CPU_FEATURES}") + if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}") + message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}") + endif() message(STATUS "Set CPU features: ${cpu_features}") + set(LIBC_CPU_FEATURES "${cpu_features}") +else() + # Populates the LIBC_CPU_FEATURES list from host. + try_run( + run_result compile_result "${CMAKE_CURRENT_BINARY_DIR}/check_${feature}" + "${CMAKE_CURRENT_BINARY_DIR}/cpu_features/check_cpu_features.cpp" + COMPILE_DEFINITIONS ${LIBC_COMPILE_OPTIONS_NATIVE} + COMPILE_OUTPUT_VARIABLE compile_output + RUN_OUTPUT_VARIABLE run_output) + if("${run_result}" EQUAL 0) + message(STATUS "Set CPU features: ${run_output}") + set(LIBC_CPU_FEATURES "${run_output}") + elseif(NOT ${compile_result}) + message(FATAL_ERROR "Failed to compile: ${compile_output}") + else() + message(FATAL_ERROR "Failed to run: ${run_output}") + endif() endif() diff --git a/libc/cmake/modules/cpu_features/check_AVX2.cpp b/libc/cmake/modules/cpu_features/check_AVX2.cpp deleted file mode 100644 index 4330308ab836e..0000000000000 --- a/libc/cmake/modules/cpu_features/check_AVX2.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/__support/cpu_features.h" - -#ifndef LIBC_TARGET_HAS_AVX2 -#error unsupported -#endif diff --git a/libc/cmake/modules/cpu_features/check_AVX512BW.cpp b/libc/cmake/modules/cpu_features/check_AVX512BW.cpp deleted file mode 100644 index 4e8cfc2f10fab..0000000000000 --- a/libc/cmake/modules/cpu_features/check_AVX512BW.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/__support/cpu_features.h" - -#ifndef LIBC_TARGET_HAS_AVX512BW -#error unsupported -#endif diff --git a/libc/cmake/modules/cpu_features/check_AVX512F.cpp b/libc/cmake/modules/cpu_features/check_AVX512F.cpp deleted file mode 100644 index 8491654b692e9..0000000000000 --- a/libc/cmake/modules/cpu_features/check_AVX512F.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/__support/cpu_features.h" - -#ifndef LIBC_TARGET_HAS_AVX512F -#error unsupported -#endif diff --git a/libc/cmake/modules/cpu_features/check_FMA.cpp b/libc/cmake/modules/cpu_features/check_FMA.cpp deleted file mode 100644 index 909875684ecfe..0000000000000 --- a/libc/cmake/modules/cpu_features/check_FMA.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/__support/cpu_features.h" - -#ifndef LIBC_TARGET_HAS_FMA -#error unsupported -#endif diff --git a/libc/cmake/modules/cpu_features/check_SSE2.cpp b/libc/cmake/modules/cpu_features/check_SSE2.cpp deleted file mode 100644 index eee2dea2d5381..0000000000000 --- a/libc/cmake/modules/cpu_features/check_SSE2.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/__support/cpu_features.h" - -#ifndef LIBC_TARGET_HAS_SSE2 -#error unsupported -#endif diff --git a/libc/cmake/modules/cpu_features/check_SSE4_2.cpp b/libc/cmake/modules/cpu_features/check_SSE4_2.cpp deleted file mode 100644 index 43586b25ed7d8..0000000000000 --- a/libc/cmake/modules/cpu_features/check_SSE4_2.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "src/__support/cpu_features.h" - -#ifndef LIBC_TARGET_HAS_SSE4_2 -#error unsupported -#endif diff --git a/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in b/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in new file mode 100644 index 0000000000000..7a3fc037c300a --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in @@ -0,0 +1,32 @@ +#include +#include + +// This file is instantiated by CMake. +// DEFINITIONS below is replaced with a set of lines like so: +// #ifdef __SSE2__ +// "SSE2", +// #endif +// +// This allows for introspection of compiler definitions. +// The output of the program is a single line of semi colon separated feature +// names. + +// MSVC is using a different set of preprocessor definitions for +// SSE and SSE2, see _M_IX86_FP in +// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros + +int main(int, char **) { + const char *strings[] = { + @DEFINITIONS@ + // If DEFINITIONS turns out to be empty, we don't want to list + // an empty array. So, we add an end of list marker. + "" + }; + const size_t size = sizeof(strings) / sizeof(strings[0]); + for (size_t i = 0; i < size; ++i) { + if (i) + putchar(';'); + fputs(strings[i], stdout); + } + return EXIT_SUCCESS; +} diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 9ea67c7da50be..2526d0cd56dba 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -33,7 +33,6 @@ add_header_library( HDRS architectures.h common.h - cpu_features.h endian.h ) diff --git a/libc/src/__support/FPUtil/FMA.h b/libc/src/__support/FPUtil/FMA.h index 7b0dbe4c1a928..f14a978f53e06 100644 --- a/libc/src/__support/FPUtil/FMA.h +++ b/libc/src/__support/FPUtil/FMA.h @@ -11,7 +11,6 @@ #include "src/__support/architectures.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #if defined(LIBC_TARGET_HAS_FMA) diff --git a/libc/src/__support/FPUtil/aarch64/FMA.h b/libc/src/__support/FPUtil/aarch64/FMA.h index 1591c9b9ee091..f742197e0477f 100644 --- a/libc/src/__support/FPUtil/aarch64/FMA.h +++ b/libc/src/__support/FPUtil/aarch64/FMA.h @@ -10,7 +10,6 @@ #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H #include "src/__support/architectures.h" -#include "src/__support/cpu_features.h" #if !defined(LLVM_LIBC_ARCH_AARCH64) #error "Invalid include" diff --git a/libc/src/__support/FPUtil/multiply_add.h b/libc/src/__support/FPUtil/multiply_add.h index 27f0081e803e5..384035e76840c 100644 --- a/libc/src/__support/FPUtil/multiply_add.h +++ b/libc/src/__support/FPUtil/multiply_add.h @@ -11,7 +11,6 @@ #include "src/__support/architectures.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" namespace __llvm_libc { namespace fputil { diff --git a/libc/src/__support/FPUtil/x86_64/FMA.h b/libc/src/__support/FPUtil/x86_64/FMA.h index 43b144331ce5c..40da101952c4a 100644 --- a/libc/src/__support/FPUtil/x86_64/FMA.h +++ b/libc/src/__support/FPUtil/x86_64/FMA.h @@ -11,7 +11,6 @@ #include "src/__support/architectures.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #if !defined(LLVM_LIBC_ARCH_X86_64) #error "Invalid include" diff --git a/libc/src/__support/architectures.h b/libc/src/__support/architectures.h index af97469f60b09..d3106daf12caa 100644 --- a/libc/src/__support/architectures.h +++ b/libc/src/__support/architectures.h @@ -49,4 +49,12 @@ #define LLVM_LIBC_ARCH_ANY_ARM #endif +#if defined(LLVM_LIBC_ARCH_AARCH64) +#define LIBC_TARGET_HAS_FMA +#elif defined(LLVM_LIBC_ARCH_X86_64) +#if (defined(__AVX2__) || defined(__FMA__)) +#define LIBC_TARGET_HAS_FMA +#endif +#endif + #endif // LLVM_LIBC_SUPPORT_ARCHITECTURES_H diff --git a/libc/src/__support/cpu_features.h b/libc/src/__support/cpu_features.h deleted file mode 100644 index c3ecd351b68f1..0000000000000 --- a/libc/src/__support/cpu_features.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- Compile time cpu feature detection ----------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// This file lists target cpu features by introspecting compiler enabled -// preprocessor definitions. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIBC_SRC_SUPPORT_CPU_FEATURES_H -#define LLVM_LIBC_SRC_SUPPORT_CPU_FEATURES_H - -#if defined(__SSE2__) -#define LIBC_TARGET_HAS_SSE2 -#endif - -#if defined(__SSE4_2__) -#define LIBC_TARGET_HAS_SSE4_2 -#endif - -#if defined(__AVX__) -#define LIBC_TARGET_HAS_AVX -#endif - -#if defined(__AVX2__) -#define LIBC_TARGET_HAS_AVX2 -#endif - -#if defined(__AVX512F__) -#define LIBC_TARGET_HAS_AVX512F -#endif - -#if defined(__AVX512BW__) -#define LIBC_TARGET_HAS_AVX512BW -#endif - -#if defined(__ARM_FEATURE_FMA) || defined(__AVX2__) -#define LIBC_TARGET_HAS_FMA -#endif - -#endif // LLVM_LIBC_SRC_SUPPORT_CPU_FEATURES_H diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp index 1b38e8dc3e859..7314b3868090b 100644 --- a/libc/src/math/generic/asinf.cpp +++ b/libc/src/math/generic/asinf.cpp @@ -13,7 +13,6 @@ #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/sqrt.h" -#include "src/__support/cpu_features.h" #include diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp index fce60cdcb723d..ebccc99dab04c 100644 --- a/libc/src/math/generic/cosf.cpp +++ b/libc/src/math/generic/cosf.cpp @@ -14,7 +14,6 @@ #include "src/__support/FPUtil/except_value_utils.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #include diff --git a/libc/src/math/generic/expm1f.cpp b/libc/src/math/generic/expm1f.cpp index 8b57522be0761..6c187b838acdb 100644 --- a/libc/src/math/generic/expm1f.cpp +++ b/libc/src/math/generic/expm1f.cpp @@ -16,7 +16,6 @@ #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #include diff --git a/libc/src/math/generic/sincosf.cpp b/libc/src/math/generic/sincosf.cpp index 991eb32b1468c..25a59bd915e95 100644 --- a/libc/src/math/generic/sincosf.cpp +++ b/libc/src/math/generic/sincosf.cpp @@ -12,7 +12,6 @@ #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #include diff --git a/libc/src/math/generic/sincosf_utils.h b/libc/src/math/generic/sincosf_utils.h index 809ceff1d7c51..38ee2784de5a9 100644 --- a/libc/src/math/generic/sincosf_utils.h +++ b/libc/src/math/generic/sincosf_utils.h @@ -12,7 +12,6 @@ #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #if defined(LIBC_TARGET_HAS_FMA) #include "range_reduction_fma.h" diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp index 836df2887825d..cae25a74381b5 100644 --- a/libc/src/math/generic/sinf.cpp +++ b/libc/src/math/generic/sinf.cpp @@ -14,7 +14,6 @@ #include "src/__support/FPUtil/PolyEval.h" #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #include diff --git a/libc/src/math/generic/tanf.cpp b/libc/src/math/generic/tanf.cpp index 8b720c48e5dec..0deb968047400 100644 --- a/libc/src/math/generic/tanf.cpp +++ b/libc/src/math/generic/tanf.cpp @@ -15,7 +15,6 @@ #include "src/__support/FPUtil/multiply_add.h" #include "src/__support/FPUtil/nearest_integer.h" #include "src/__support/common.h" -#include "src/__support/cpu_features.h" #include diff --git a/libc/src/math/generic/tanhf.cpp b/libc/src/math/generic/tanhf.cpp index 8b6771b768821..22b95870f4c69 100644 --- a/libc/src/math/generic/tanhf.cpp +++ b/libc/src/math/generic/tanhf.cpp @@ -8,7 +8,6 @@ #include "src/math/tanhf.h" #include "src/__support/FPUtil/FPBits.h" -#include "src/__support/cpu_features.h" #include "src/math/generic/explogxf.h" namespace __llvm_libc { diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 2088391847891..3d2a8d59eb542 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -79,7 +79,6 @@ libc_support_library( hdrs = [ "src/__support/architectures.h", "src/__support/common.h", - "src/__support/cpu_features.h", "src/__support/endian.h", ], )