From 8b9743eb407fb1a5c09041b9ca39cf59cc3ce6b3 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Thu, 11 Apr 2024 20:46:14 +0200 Subject: [PATCH] CMake: Change build flags to use SSE42 if available This cleans up our `TEST_SSE_SUPPORT` macro to only test for SSE42 and passes the flags to the CMAKE_C/CXX_FLAGS the cpu check module needed to move to its own folder since the flags at the end of a CMakeLists.txt appear to be used for all targets inside a CMakeLists file and cpu_check cannot be build with sse42 flags. This only affects Mac/Linux since MSVC has no buildflags to target SSE42 Pull Request: https://projects.blender.org/blender/blender/pulls/118468 --- CMakeLists.txt | 36 +++++++-------- build_files/cmake/macros.cmake | 44 +++++++------------ source/blender/CMakeLists.txt | 4 ++ source/blender/cpucheck/CMakeLists.txt | 26 +++++++++++ .../cpucheck/cpu_check.cc} | 0 source/creator/CMakeLists.txt | 19 -------- 6 files changed, 64 insertions(+), 65 deletions(-) create mode 100644 source/blender/cpucheck/CMakeLists.txt rename source/{creator/creator_cpu_check.cc => blender/cpucheck/cpu_check.cc} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 669d17f61f2..e4f8cbc3776 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1399,13 +1399,12 @@ endif() # Test SIMD support, before platform includes to determine if sse2neon is needed. if(WITH_CPU_SIMD) - set(COMPILER_SSE_FLAG) - set(COMPILER_SSE2_FLAG) + set(COMPILER_SSE42_FLAG) # Test Neon first since macOS Arm can compile and run x86-64 SSE binaries. test_neon_support() if(NOT SUPPORT_NEON_BUILD) - test_sse_support(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG) + test_sse_support(COMPILER_SSE42_FLAG) endif() endif() @@ -1445,8 +1444,6 @@ endif() # Enable SIMD support if detected by `test_sse_support()` or `test_neon_support()`. # -# This is done globally, so that all modules can use it if available, and -# because these are used in headers used by many modules. if(WITH_CPU_SIMD) if(SUPPORT_NEON_BUILD) # Neon @@ -1456,15 +1453,20 @@ if(WITH_CPU_SIMD) endif() else() # SSE - if(SUPPORT_SSE_BUILD) - string(PREPEND PLATFORM_CFLAGS "${COMPILER_SSE_FLAG} ") - add_definitions(-D__SSE__ -D__MMX__) - endif() - if(SUPPORT_SSE2_BUILD) - string(APPEND PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG}") - add_definitions(-D__SSE2__) - if(NOT SUPPORT_SSE_BUILD) # don't double up - add_definitions(-D__MMX__) + if(SUPPORT_SSE42_BUILD) + string(APPEND CMAKE_CXX_FLAGS " ${COMPILER_SSE42_FLAG}") + string(APPEND CMAKE_C_FLAGS " ${COMPILER_SSE42_FLAG}") + # MSVC doesn't define any of these and only does the AVX and higher flags. + # For consistency we define these flags for MSVC. + if(WIN32) + add_compile_definitions( + __MMX__ + __SSE__ + __SSE2__ + __SSE3__ + __SSE4_1__ + __SSE4_2__ + ) endif() endif() endif() @@ -1479,10 +1481,8 @@ if(FIRST_RUN) else() message(STATUS "Neon SIMD instructions detected but unused, requires sse2neon") endif() - elseif(SUPPORT_SSE2_BUILD) - message(STATUS "SSE2 SIMD instructions enabled") - elseif(SUPPORT_SSE_BUILD) - message(STATUS "SSE SIMD instructions enabled") + elseif(SUPPORT_SSE42_BUILD) + message(STATUS "SSE42 SIMD instructions enabled") else() message(STATUS "No SIMD instructions detected") endif() diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 0b3b071c70d..f78aa93c27d 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -540,49 +540,37 @@ function(setup_platform_linker_libs endfunction() macro(TEST_SSE_SUPPORT - _sse_flags - _sse2_flags) + _sse42_flags) include(CheckCSourceRuns) # message(STATUS "Detecting SSE support") if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) - set(${_sse_flags} "-msse") - set(${_sse2_flags} "-msse2") + set(${_sse42_flags} "-march=x86-64-v2") elseif(MSVC) - # x86_64 has this auto enabled - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(${_sse_flags} "") - set(${_sse2_flags} "") - else() - set(${_sse_flags} "/arch:SSE") - set(${_sse2_flags} "/arch:SSE2") - endif() + # msvc has no specific build flags for SSE42, but when using intrinsics it will + # generate the right instructions. + set(${_sse42_flags} "") elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel") - set(${_sse_flags} "") # icc defaults to -msse - set(${_sse2_flags} "") # icc defaults to -msse2 + if(WIN32) + set(${_sse42_flags} "/QxSSE4.2") + else() + set(${_sse42_flags} "-xsse4.2") + endif() else() message(WARNING "SSE flags for this compiler: '${CMAKE_C_COMPILER_ID}' not known") - set(${_sse_flags}) - set(${_sse2_flags}) + set(${_sse42_flags}) endif() - set(CMAKE_REQUIRED_FLAGS "${${_sse_flags}} ${${_sse2_flags}}") + set(CMAKE_REQUIRED_FLAGS "${${_sse42_flags}}") - if(NOT DEFINED SUPPORT_SSE_BUILD) - # result cached - check_c_source_runs(" - #include - int main(void) { __m128 v = _mm_setzero_ps(); return 0; }" - SUPPORT_SSE_BUILD) - endif() - - if(NOT DEFINED SUPPORT_SSE2_BUILD) + if(NOT DEFINED SUPPORT_SSE42_BUILD) # result cached check_c_source_runs(" + #include #include - int main(void) { __m128d v = _mm_setzero_pd(); return 0; }" - SUPPORT_SSE2_BUILD) + int main(void) { __m128i v = _mm_setzero_si128(); v = _mm_cmpgt_epi64(v,v); return 0; }" + SUPPORT_SSE42_BUILD) endif() unset(CMAKE_REQUIRED_FLAGS) diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 25854e5ac79..a40b476eec1 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -181,3 +181,7 @@ endif() if(WITH_FREESTYLE) add_subdirectory(freestyle) endif() + +if(WITH_CPU_CHECK) + add_subdirectory(cpucheck) +endif() diff --git a/source/blender/cpucheck/CMakeLists.txt b/source/blender/cpucheck/CMakeLists.txt new file mode 100644 index 00000000000..6c08260f9ff --- /dev/null +++ b/source/blender/cpucheck/CMakeLists.txt @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2024 Blender Authors +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# The cpu check module cannot build with sse42 since it will be executed +# by cpus that may not support these instructions + +if(COMPILER_SSE42_FLAG) + remove_cc_flag("${COMPILER_SSE42_FLAG}") +endif() +add_library(blender_cpu_check SHARED cpu_check.cc) + +target_link_libraries(blender_cpu_check PRIVATE ${PLATFORM_LINKLIBS}) +target_compile_definitions(blender_cpu_check PUBLIC WITH_CPU_CHECK) + +if(NOT WIN32) + set(_LIB_SUB_FOLDER "lib/") +endif() + +set_target_properties(blender_cpu_check + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}" +) + +unset(_LIB_SUB_FOLDER) diff --git a/source/creator/creator_cpu_check.cc b/source/blender/cpucheck/cpu_check.cc similarity index 100% rename from source/creator/creator_cpu_check.cc rename to source/blender/cpucheck/cpu_check.cc diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 289d05c658d..885ea2510ae 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -333,29 +333,10 @@ if(WITH_PYTHON_MODULE) else() add_executable(blender ${EXETYPE} ${SRC}) if(WITH_CPU_CHECK) - target_compile_definitions(blender PRIVATE WITH_CPU_CHECK) - # we cannot directly link against any blender libraries for the cpu_check module - # as they may have been build for an ISA that is unsupported by the CPU - # running this code. - add_library(blender_cpu_check SHARED - creator_cpu_check.cc - ) - target_link_libraries(blender_cpu_check - PRIVATE ${PLATFORM_LINKLIBS} - ) # blender_cpu_check *NEEDS* to be linked first, there can be no exceptions # to this, this is to ensure this will be the first code to run once the # blender binary has been loaded by the OS. target_link_libraries(blender PRIVATE blender_cpu_check) - if(NOT WIN32) - set(_LIB_SUB_FOLDER "lib/") - endif() - set_target_properties(blender_cpu_check - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${_LIB_SUB_FOLDER}" - ) - unset(_LIB_SUB_FOLDER) endif() if(WIN32) add_executable(blender-launcher WIN32