Hi hackers,
After having worked on [1], I tried to make use of the Intel's ICX compiler [2].
While the compilation was ok for both autoconf and meson (meson version has to
be
0.64 or greater, see [3] that added the ICX support), I ran into a couple of
issues
when running the test suite.
1/ Issue on floating point
The tests were failing with issues such as:
--- /home/postgres/postgresql/postgres/src/test/regress/expected/time.out
+++ /home/postgres/postgresql/postgres/src/test/regress/results/time.out
@@ -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 (see [4]).
This is the same class of optimizations that we guard against by rejecting
-ffast-math in autoconf (BTW, we don't guard against in meson, I think we should
do the same, and it has been proposed in [5]).
The issue is solved by using the ICX -fp-model=precise flag (see [6]).
2/ Issue on ICX's default runtime libraries
For example, I was observing:
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 issue is solved by making use of -no-intel-lib ([7]).
I think that it makes sense to have ICX working (we took care of ICC in the
past),
so PFA, a patch implementing those changes for both autoconf and meson.
Remarks:
For autoconf, ICX is detected thanks to the __INTEL_LLVM_COMPILER macro (see,
[8]) and for meson with the compiler id "intel-llvm" (see [9]).
With those in place the tests run without any issues.
Regarding -no-intel-lib, we may want specific libraries to exclude, but
excluding
all looks safer.
We could also think about having some BF animals with ICX and/or maybe a
dedicated
cirrus task.
Looking forward to your feedback.
[1]:
https://postgr.es/m/aa73q1aT0A3/vke/%40ip-10-97-1-34.eu-west-3.compute.internal
[2]:
https://www.intel.com/content/www/us/en/developer/articles/technical/adoption-of-llvm-complete-icx.html
[3]: https://mesonbuild.com/Release-notes-for-0-64-0.html
[4]:
https://www.intel.com/content/www/us/en/developer/articles/guide/porting-guide-for-icc-users-to-dpcpp-or-icx.html
[5]:
https://postgr.es/m/abFXfKC8zR0Oclon%40ip-10-97-1-34.eu-west-3.compute.internal
[6]:
https://www.intel.com/content/www/us/en/docs/dpcpp-cpp-compiler/developer-guide-reference/2025-1/fp-model-fp.html
[7]:
https://www.intel.com/content/www/us/en/docs/dpcpp-cpp-compiler/developer-guide-reference/2025-1/no-intel-lib-qno-intel-lib.html
[8]:
https://www.intel.com/content/www/us/en/developer/articles/technical/use-predefined-macros-for-specific-code-for-intel-dpcpp-compiler-intel-cpp-compiler-intel-cpp-compiler-classic.html
[9]: https://mesonbuild.com/Reference-tables.html
Regards,
--
Bertrand Drouvot
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com
>From ddda52b12d56b2e7f90f7a107987df3e310511bf Mon Sep 17 00:00:00 2001
From: Bertrand Drouvot <[email protected]>
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