diff --git a/cmake/mode.common.cmake b/cmake/mode.common.cmake index f82770422f..fe7b340f8b 100644 --- a/cmake/mode.common.cmake +++ b/cmake/mode.common.cmake @@ -39,3 +39,20 @@ check_cxx_compiler_flag(${_stack_usage_threshold_flag} _stack_usage_flag_support if(_stack_usage_flag_supported) string(APPEND CMAKE_CXX_FLAGS " ${_stack_usage_threshold_flag}") endif() + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 16) + # workaround https://github.com/llvm/llvm-project/issues/62842 + set(_original_level "${Seastar_OptimizationLevel_${build_mode}}") + set(_safe_level "0") + if(NOT _original_level STREQUAL _safe_level) + message(WARNING + "Changing optimization level from -O${_original_level} to -O${_safe_level} " + "due to https://github.com/llvm/llvm-project/issues/62842. " + "Please note -O0 is very slow that some tests might fail.") + string(REPLACE " -O${_original_level} " " -O${_safe_level} " + CMAKE_CXX_FLAGS_${build_mode} + "${CMAKE_CXX_FLAGS_${build_mode}}") + endif() + unset(_original_level) + unset(_safe_level) +endif() diff --git a/configure.py b/configure.py index 891cfe30d0..f20f8f5f33 100755 --- a/configure.py +++ b/configure.py @@ -18,6 +18,7 @@ import sys import tempfile import textwrap from distutils.spawn import find_executable +from pkg_resources import parse_version curdir = os.getcwd() @@ -163,6 +164,41 @@ def flag_supported(flag, compiler): return try_compile(flags=['-Werror'] + split, compiler=compiler) +class OptimizationLevel: + warned = False + + @classmethod + def _warn(cls, safe_level) -> None: + if cls.warned: + # only prints this warning for a single time + return + print('\033[91mWARN\033[00m: ' + f'Changing optimization level to "-O{safe_level}" ' + 'due to https://github.com/llvm/llvm-project/issues/62842. ' + 'Please note -O0 is so slow that some tests might fail.') + cls.warned = True + + def __call__(self, cxx_compiler, default_level): + # workaround https://github.com/llvm/llvm-project/issues/62842 + if 'clang' not in cxx_compiler: + return default_level + + proc = subprocess.run([cxx_compiler, '--version'], + capture_output=True, + check=True, + text=True) + matched = re.match(r'clang version (\d+\.\d+.\d+)', proc.stdout) + if matched is None: + raise Exception(f'Unable to tell version of {cxx_compiler}') + if parse_version(matched.group(1)) < parse_version('16.0.0'): + return default_level + safe_level = '0' + if default_level == safe_level: + return default_level + self._warn(safe_level) + return safe_level +optimization_level = OptimizationLevel() + def linker_flags(compiler): src_main = 'int main(int argc, char **argv) { return 0; }' link_flags = ['-fuse-ld=lld'] @@ -1424,7 +1460,8 @@ for mode_level in args.mode_o_levels: modes[mode]['optimization-level'] = level for mode in modes: - modes[mode]['cxxflags'] += f' -O{modes[mode]["optimization-level"]}' + level = optimization_level(args.cxx, modes[mode]["optimization-level"]) + modes[mode]['cxxflags'] += f' -O{level}' optimization_flags = [ '--param inline-unit-growth=300', # gcc