From ddda52b12d56b2e7f90f7a107987df3e310511bf Mon Sep 17 00:00:00 2001 From: Bertrand Drouvot Date: Tue, 10 Mar 2026 13:07:50 +0000 Subject: [PATCH v1] Make Intel's ICX compiler working Using ICX led to two issues: 1/ Issue on floating point The tests were failing with issues such as: @@ -225,8 +225,8 @@ (1 row) SELECT date_part('epoch', TIME '2020-05-26 13:30:25.575401'); - date_part --------------- - 48625.575401 + date_part +-------------------- + 48625.575400999995 The reason is that ICX defaults to -fp-model=fast enabling unsafe floating-point optimizations. This is the same class of optimizations that we guard against by rejecting -ffast-math in autoconf. The commit fixes it by using the ICX -fp-model=precise flag. 2/ Issue on ICX's default runtime libraries The tests were failing with issues such as: postgres: postgres regression [local] CREATE SUBSCRIPTION: Relink `/opt/intel/oneapi/compiler/2025.3/lib/libimf.so' with `/lib/x86_64-linux-gnu/libm.so.6' for IFUNC symbol `cosf' followed by a SIGSEGV. The reason is that ICX by default links against Intel runtime libraries such as libimf.so, which provide IFUNC-based replacements for standard math functions (e.g. cosf). When shared libraries built with ICX are loaded into a process that also uses the system libm.so.6, the dynamic linker encounters conflicting IFUNC resolvers and segfaults. The commit fixes it by using the ICX -no-intel-lib flag. For autoconf, ICX is detected thanks to the __INTEL_LLVM_COMPILER macro and for meson with the compiler id "intel-llvm". --- configure | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 25 +++++- meson.build | 33 ++++++++ 3 files changed, 275 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 42621ecd051..741d0163b0c 100755 --- a/configure +++ b/configure @@ -4862,7 +4862,7 @@ fi fi # have_cxx -# Check if it's Intel's compiler, which (usually) pretends to be gcc, +# Check if it's Intel's ICC compiler, which (usually) pretends to be gcc, # but has idiosyncrasies of its own. We assume icc will define # __INTEL_COMPILER regardless of CFLAGS. cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -4885,6 +4885,28 @@ else fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Check if it's Intel's ICX compiler. +# ICX defines __INTEL_LLVM_COMPILER but not __INTEL_COMPILER, so it +# falls through as ICC=no above. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __INTEL_LLVM_COMPILER +choke me +#endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ICX=yes +else + ICX=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # # LLVM @@ -6901,6 +6923,201 @@ if test x"$pgac_cv_prog_CXX_cxxflags__fno_strict_aliasing" = x"yes"; then fi +fi + +# ICX is Clang-based and takes the GCC flag path above, but also requires these +# additional flags. +if test "$ICX" = yes; then + # ICX by default links against Intel runtime libraries such as libimf.so, + # which provide IFUNC-based replacements for standard math functions (e.g. + # cosf). When shared libraries built with ICX are loaded into a process that + # also uses the system libm.so.6, the dynamic linker encounters conflicting + # IFUNC resolvers and segfaults. Use system libraries instead to avoid this. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -no-intel-lib, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -no-intel-lib, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__no_intel_lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS} -no-intel-lib" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__no_intel_lib=yes +else + pgac_cv_prog_CC_cflags__no_intel_lib=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__no_intel_lib" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__no_intel_lib" >&6; } +if test x"$pgac_cv_prog_CC_cflags__no_intel_lib" = x"yes"; then + CFLAGS="${CFLAGS} -no-intel-lib" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -no-intel-lib, for CXXFLAGS" >&5 +$as_echo_n "checking whether ${CXX} supports -no-intel-lib, for CXXFLAGS... " >&6; } +if ${pgac_cv_prog_CXX_cxxflags__no_intel_lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CXX} +CXXFLAGS="${CXXFLAGS} -no-intel-lib" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CXX_cxxflags__no_intel_lib=yes +else + pgac_cv_prog_CXX_cxxflags__no_intel_lib=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__no_intel_lib" >&5 +$as_echo "$pgac_cv_prog_CXX_cxxflags__no_intel_lib" >&6; } +if test x"$pgac_cv_prog_CXX_cxxflags__no_intel_lib" = x"yes"; then + CXXFLAGS="${CXXFLAGS} -no-intel-lib" +fi + + + # ICX defaults to -fp-model=fast enabling unsafe floating-point optimizations. + # This is the same class of optimizations that we guard against by rejecting + # -ffast-math below. Use -fp-model=precise instead. + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -fp-model=precise, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -fp-model=precise, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__fp_model_precise+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS} -fp-model=precise" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__fp_model_precise=yes +else + pgac_cv_prog_CC_cflags__fp_model_precise=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__fp_model_precise" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__fp_model_precise" >&6; } +if test x"$pgac_cv_prog_CC_cflags__fp_model_precise" = x"yes"; then + CFLAGS="${CFLAGS} -fp-model=precise" +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -fp-model=precise, for CXXFLAGS" >&5 +$as_echo_n "checking whether ${CXX} supports -fp-model=precise, for CXXFLAGS... " >&6; } +if ${pgac_cv_prog_CXX_cxxflags__fp_model_precise+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CXXFLAGS=$CXXFLAGS +pgac_save_CXX=$CXX +CXX=${CXX} +CXXFLAGS="${CXXFLAGS} -fp-model=precise" +ac_save_cxx_werror_flag=$ac_cxx_werror_flag +ac_cxx_werror_flag=yes +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + pgac_cv_prog_CXX_cxxflags__fp_model_precise=yes +else + pgac_cv_prog_CXX_cxxflags__fp_model_precise=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_cxx_werror_flag=$ac_save_cxx_werror_flag +CXXFLAGS="$pgac_save_CXXFLAGS" +CXX="$pgac_save_CXX" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__fp_model_precise" >&5 +$as_echo "$pgac_cv_prog_CXX_cxxflags__fp_model_precise" >&6; } +if test x"$pgac_cv_prog_CXX_cxxflags__fp_model_precise" = x"yes"; then + CXXFLAGS="${CXXFLAGS} -fp-model=precise" +fi + + fi # If the compiler knows how to hide symbols, add the switch needed for that to diff --git a/configure.ac b/configure.ac index 61ec895d23c..3b0cbc3c957 100644 --- a/configure.ac +++ b/configure.ac @@ -428,13 +428,19 @@ fi fi # have_cxx -# Check if it's Intel's compiler, which (usually) pretends to be gcc, +# Check if it's Intel's ICC compiler, which (usually) pretends to be gcc, # but has idiosyncrasies of its own. We assume icc will define # __INTEL_COMPILER regardless of CFLAGS. AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [@%:@ifndef __INTEL_COMPILER choke me @%:@endif])], [ICC=yes], [ICC=no]) +# Check if it's Intel's ICX compiler. +# ICX defines __INTEL_LLVM_COMPILER but not __INTEL_COMPILER, so it +# falls through as ICC=no above. +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [@%:@ifndef __INTEL_LLVM_COMPILER +choke me +@%:@endif])], [ICX=yes], [ICX=no]) # # LLVM @@ -649,6 +655,23 @@ elif test "$ICC" = yes; then PGAC_PROG_CXX_CFLAGS_OPT([-fno-strict-aliasing]) fi +# ICX is Clang-based and takes the GCC flag path above, but also requires these +# additional flags. +if test "$ICX" = yes; then + # ICX by default links against Intel runtime libraries such as libimf.so, + # which provide IFUNC-based replacements for standard math functions (e.g. + # cosf). When shared libraries built with ICX are loaded into a process that + # also uses the system libm.so.6, the dynamic linker encounters conflicting + # IFUNC resolvers and segfaults. Use system libraries instead to avoid this. + PGAC_PROG_CC_CFLAGS_OPT([-no-intel-lib]) + PGAC_PROG_CXX_CFLAGS_OPT([-no-intel-lib]) + # ICX defaults to -fp-model=fast enabling unsafe floating-point optimizations. + # This is the same class of optimizations that we guard against by rejecting + # -ffast-math below. Use -fp-model=precise instead. + PGAC_PROG_CC_CFLAGS_OPT([-fp-model=precise]) + PGAC_PROG_CXX_CFLAGS_OPT([-fp-model=precise]) +fi + # If the compiler knows how to hide symbols, add the switch needed for that to # CFLAGS_SL_MODULE and define HAVE_VISIBILITY_ATTRIBUTE. # diff --git a/meson.build b/meson.build index 2df54409ca6..2a5c35f4072 100644 --- a/meson.build +++ b/meson.build @@ -2183,6 +2183,26 @@ if have_cxx cxxflags += cxx.get_supported_arguments(common_functional_flags) endif +# ICX is Clang-based and takes the flags above, but also requires these +# additional flags. +if cc.get_id() == 'intel-llvm' + # ICX by default links against Intel runtime libraries such as libimf.so, + # which provide IFUNC-based replacements for standard math functions (e.g. + # cosf). When shared libraries built with ICX are loaded into a process that + # also uses the system libm.so.6, the dynamic linker encounters conflicting + # IFUNC resolvers and segfaults. Use system libraries instead to avoid this. + cflags += cc.get_supported_arguments(['-no-intel-lib']) + if have_cxx + cxxflags += cxx.get_supported_arguments(['-no-intel-lib']) + endif + # ICX defaults to -fp-model=fast enabling unsafe floating-point optimizations. + # Use -fp-model=precise instead. + cflags += cc.get_supported_arguments(['-fp-model=precise']) + if have_cxx + cxxflags += cxx.get_supported_arguments(['-fp-model=precise']) + endif +endif + vectorize_cflags = cc.get_supported_arguments(['-ftree-vectorize']) unroll_loops_cflags = cc.get_supported_arguments(['-funroll-loops']) @@ -3182,6 +3202,19 @@ add_project_arguments(cppflags, language: ['cpp']) add_project_arguments(cxxflags_warn, language: ['cpp']) add_project_link_arguments(ldflags, language: ['c', 'cpp']) +# ICX by default links against Intel runtime libraries such as libimf.so, +# which provide IFUNC-based replacements for standard math functions (e.g. +# cosf). When shared libraries built with ICX are loaded into a process that +# also uses the system libm.so.6, the dynamic linker encounters conflicting +# IFUNC resolvers and segfaults. Use system libraries instead to avoid this. +if cc.get_id() == 'intel-llvm' + add_project_link_arguments( + cc.get_supported_link_arguments(['-no-intel-lib']), language: 'c') + if have_cxx and cxx.get_id() == 'intel-llvm' + add_project_link_arguments( + cxx.get_supported_link_arguments(['-no-intel-lib']), language: 'cpp') + endif +endif # Collect a number of lists of things while recursing through the source # tree. Later steps then can use those. -- 2.34.1