From: Guillaume Chatelet Date: Tue, 24 Jan 2023 16:04:10 +0000 (+0000) Subject: [reland][libc][NFC] Detect host CPU features using try_compile instead of try_run. X-Git-Tag: upstream/17.0.6~19804 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c84d74f5bfe810744de1268eb0516a6622e4aa73;p=platform%2Fupstream%2Fllvm.git [reland][libc][NFC] Detect host CPU features using try_compile instead of try_run. This implements the same behavior as D141997 but makes sure that the same detection mechanism is used between CMake and source code. Differential Revision: https://reviews.llvm.org/D142108 --- diff --git a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake index b97b03f..9a18ac0 100644 --- a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake +++ b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake @@ -44,44 +44,32 @@ function(_intersection output_var list1 list2) set(${output_var} ${tmp} PARENT_SCOPE) endfunction() -# Generates a cpp file to introspect the compiler defined flags. -function(_generate_check_code) +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) foreach(feature IN LISTS ALL_CPU_FEATURES) - set(DEFINITIONS - "${DEFINITIONS} -#ifdef __${feature}__ - \"${feature}\", -#endif") + 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() endforeach() - 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() +endif() -set(LIBC_CPU_FEATURES "" CACHE PATH "Host supported CPU features") +set(LIBC_CPU_FEATURES ${AVAILABLE_CPU_FEATURES} CACHE STRING "Host supported CPU features") -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}") +_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() - # 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() + message(STATUS "Set CPU features: ${cpu_features}") endif() diff --git a/libc/cmake/modules/cpu_features/check_AVX2.cpp b/libc/cmake/modules/cpu_features/check_AVX2.cpp new file mode 100644 index 0000000..4330308 --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_AVX2.cpp @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..4e8cfc2 --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_AVX512BW.cpp @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..8491654 --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_AVX512F.cpp @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..9098756 --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_FMA.cpp @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..eee2dea --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_SSE2.cpp @@ -0,0 +1,5 @@ +#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 new file mode 100644 index 0000000..43586b2 --- /dev/null +++ b/libc/cmake/modules/cpu_features/check_SSE4_2.cpp @@ -0,0 +1,5 @@ +#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 deleted file mode 100644 index 7a3fc03..0000000 --- a/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in +++ /dev/null @@ -1,32 +0,0 @@ -#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 2526d0c..9ea67c7 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -33,6 +33,7 @@ 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 f14a978..7b0dbe4 100644 --- a/libc/src/__support/FPUtil/FMA.h +++ b/libc/src/__support/FPUtil/FMA.h @@ -11,6 +11,7 @@ #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 f742197..1591c9b 100644 --- a/libc/src/__support/FPUtil/aarch64/FMA.h +++ b/libc/src/__support/FPUtil/aarch64/FMA.h @@ -10,6 +10,7 @@ #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 384035e..27f0081 100644 --- a/libc/src/__support/FPUtil/multiply_add.h +++ b/libc/src/__support/FPUtil/multiply_add.h @@ -11,6 +11,7 @@ #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 40da101..43b1443 100644 --- a/libc/src/__support/FPUtil/x86_64/FMA.h +++ b/libc/src/__support/FPUtil/x86_64/FMA.h @@ -11,6 +11,7 @@ #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 d3106da..af97469 100644 --- a/libc/src/__support/architectures.h +++ b/libc/src/__support/architectures.h @@ -49,12 +49,4 @@ #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 new file mode 100644 index 0000000..68bf6fa --- /dev/null +++ b/libc/src/__support/cpu_features.h @@ -0,0 +1,43 @@ +//===-- 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__) || defined(__FMA__) +#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 7314b38..1b38e8d 100644 --- a/libc/src/math/generic/asinf.cpp +++ b/libc/src/math/generic/asinf.cpp @@ -13,6 +13,7 @@ #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 ebccc99..fce60cd 100644 --- a/libc/src/math/generic/cosf.cpp +++ b/libc/src/math/generic/cosf.cpp @@ -14,6 +14,7 @@ #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 6c187b8..8b57522 100644 --- a/libc/src/math/generic/expm1f.cpp +++ b/libc/src/math/generic/expm1f.cpp @@ -16,6 +16,7 @@ #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 25a59bd..991eb32 100644 --- a/libc/src/math/generic/sincosf.cpp +++ b/libc/src/math/generic/sincosf.cpp @@ -12,6 +12,7 @@ #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 a193216..358c1cf 100644 --- a/libc/src/math/generic/sincosf_utils.h +++ b/libc/src/math/generic/sincosf_utils.h @@ -12,6 +12,7 @@ #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 cae25a7..836df28 100644 --- a/libc/src/math/generic/sinf.cpp +++ b/libc/src/math/generic/sinf.cpp @@ -14,6 +14,7 @@ #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 0deb968..8b720c4 100644 --- a/libc/src/math/generic/tanf.cpp +++ b/libc/src/math/generic/tanf.cpp @@ -15,6 +15,7 @@ #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 22b9587..8b6771b 100644 --- a/libc/src/math/generic/tanhf.cpp +++ b/libc/src/math/generic/tanhf.cpp @@ -8,6 +8,7 @@ #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 be4dafd..e9d3a55 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -79,6 +79,7 @@ libc_support_library( hdrs = [ "src/__support/architectures.h", "src/__support/common.h", + "src/__support/cpu_features.h", "src/__support/endian.h", ], )