[PATCH v2] x86-64: Properly compile ISA optimized modf and modff
H.J. Lu
hjl.tools@gmail.com
Fri Jul 18 17:09:39 GMT 2025
On Fri, Jul 18, 2025 at 10:03 AM Andreas K. Huettel
<dilfridge@gentoo.org> wrote:
>
> Am Freitag, 18. Juli 2025, 15:13:04 Mitteleuropäische Sommerzeit schrieb Adhemerval Zanella Netto:
> >
> > On 18/07/25 08:33, H.J. Lu wrote:
> > > There are 3 variants of modf and modff: SSE2, SSE4.1 and AVX. s_modf.c
> > > and s_modff.c include the generic implementation compiled with the minimum
> > > x86 ISA level. The IFUNC selector is used only if the minimum ISA level
> > > is less than AVX. SSE4.1 variant is included only if the ISA level is
> > > less than SSE4.1. AVX variant is included only the ISA level is less than
> > > AVX.
> > >
> > > AVX variant should be compiled with -mavx, not -msse2avx -DSSE2AVX which
> > > are used to encode SSE assembly sources with EVEX encoding.
> > >
> > > The routines that are shared between libc and libm should use different
> > > rules to avoid using the same MODULE_NAME, to avoid potential issues
> > > like BZ #33165 where __stack_chk_fail not being routed to the internal
> > > symbol.
> > >
> > > Tested with -march=x86-64, -march=x86-64-v2, -march=x86-64-v3 and
> > > -march=x86-64-v4.
> > >
> > > This fixes BZ #33165 and BZ #33173.
> > >
> > > Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> > > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> >
> > LGTM, thanks.
> >
> > Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
>
> In with it now, and then let's machine-test it.
I am checking it in.
>
> >
> > > ---
> > > sysdeps/x86/configure | 4 ++
> > > sysdeps/x86/configure.ac | 2 +
> > > sysdeps/x86_64/fpu/multiarch/Makefile | 50 ++++++++-----------
> > > .../x86_64/fpu/multiarch/ifunc-sse4_1-avx.h | 41 +++++++++++++++
> > > sysdeps/x86_64/fpu/multiarch/s_modf-avx.c | 2 +
> > > sysdeps/x86_64/fpu/multiarch/s_modf-c.c | 2 -
> > > sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c | 6 +--
> > > sysdeps/x86_64/fpu/multiarch/s_modf.c | 10 +++-
> > > sysdeps/x86_64/fpu/multiarch/s_modff-avx.c | 2 +
> > > sysdeps/x86_64/fpu/multiarch/s_modff-c.c | 2 -
> > > sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c | 6 +--
> > > sysdeps/x86_64/fpu/multiarch/s_modff.c | 10 +++-
> > > 12 files changed, 90 insertions(+), 47 deletions(-)
> > > create mode 100644 sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h
> > > delete mode 100644 sysdeps/x86_64/fpu/multiarch/s_modf-c.c
> > > delete mode 100644 sysdeps/x86_64/fpu/multiarch/s_modff-c.c
> > >
> > > diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
> > > index c7ea9ac6ad..dff26e9b83 100644
> > > --- a/sysdeps/x86/configure
> > > +++ b/sysdeps/x86/configure
> > > @@ -171,8 +171,12 @@ fi
> > > config_vars="$config_vars
> > > have-x86-isa-level = $libc_cv_have_x86_isa_level"
> > > config_vars="$config_vars
> > > +x86-isa-level-2-or-above = 2 3 4"
> > > +config_vars="$config_vars
> > > x86-isa-level-3-or-above = 3 4"
> > > config_vars="$config_vars
> > > +x86-isa-level-4-or-above = 4"
> > > +config_vars="$config_vars
> > > enable-x86-isa-level = $libc_cv_include_x86_isa_level"
> > >
> > >
> > > diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
> > > index 031f91719d..54960a71c9 100644
> > > --- a/sysdeps/x86/configure.ac
> > > +++ b/sysdeps/x86/configure.ac
> > > @@ -117,7 +117,9 @@ else
> > > AC_DEFINE_UNQUOTED(MINIMUM_X86_ISA_LEVEL, $libc_cv_have_x86_isa_level)
> > > fi
> > > LIBC_CONFIG_VAR([have-x86-isa-level], [$libc_cv_have_x86_isa_level])
> > > +LIBC_CONFIG_VAR([x86-isa-level-2-or-above], [2 3 4])
> > > LIBC_CONFIG_VAR([x86-isa-level-3-or-above], [3 4])
> > > +LIBC_CONFIG_VAR([x86-isa-level-4-or-above], [4])
> > > LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
> > >
> > > dnl Check if TEST_CC supports -mfpmath=387
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/Makefile b/sysdeps/x86_64/fpu/multiarch/Makefile
> > > index 81a870d3b1..708b14297f 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/Makefile
> > > +++ b/sysdeps/x86_64/fpu/multiarch/Makefile
> > > @@ -26,19 +26,21 @@ CFLAGS-s_sinf-fma.c = -mfma -mavx2
> > > CFLAGS-s_cosf-fma.c = -mfma -mavx2
> > > CFLAGS-s_sincosf-fma.c = -mfma -mavx2
> > >
> > > +# Check if ISA level is 2 or above.
> > > +ifeq (,$(filter $(have-x86-isa-level),$(x86-isa-level-2-or-above)))
> > > +sysdep_calls += \
> > > + s_modf-sse4_1 \
> > > + s_modff-sse4_1 \
> > > +# sysdep_calls
> > > +endif
> > > +
> > > # Check if ISA level is 3 or above.
> > > ifneq (,$(filter $(have-x86-isa-level),$(x86-isa-level-3-or-above)))
> > > -sysdep_routines += \
> > > - s_modf-avx \
> > > - s_modff-avx \
> > > -# sysdep_routines
> > > libm-sysdep_routines += \
> > > s_ceil-avx \
> > > s_ceilf-avx \
> > > s_floor-avx \
> > > s_floorf-avx \
> > > - s_modf-avx \
> > > - s_modff-avx \
> > > s_nearbyint-avx \
> > > s_nearbyintf-avx \
> > > s_rint-avx \
> > > @@ -49,6 +51,10 @@ libm-sysdep_routines += \
> > > s_truncf-avx \
> > > # libm-sysdep_routines
> > > else
> > > +sysdep_calls += \
> > > + s_modf-avx \
> > > + s_modff-avx \
> > > +# sysdep_calls
> > > ifeq (no,$(have-x86-apx))
> > > libm-sysdep_routines += \
> > > e_asin-fma4 \
> > > @@ -62,10 +68,6 @@ libm-sysdep_routines += \
> > > s_tan-fma4 \
> > > # libm-sysdep_routines
> > > endif
> > > -sysdep_routines += \
> > > - s_modf-sse4_1 \
> > > - s_modff-sse4_1 \
> > > -# sysdep_routines
> > > libm-sysdep_routines += \
> > > e_asin-fma \
> > > e_atan2-avx \
> > > @@ -95,8 +97,6 @@ libm-sysdep_routines += \
> > > s_floor-sse4_1 \
> > > s_floorf-sse4_1 \
> > > s_log1p-fma \
> > > - s_modf-sse4_1 \
> > > - s_modff-sse4_1 \
> > > s_nearbyint-sse4_1 \
> > > s_nearbyintf-sse4_1 \
> > > s_rint-sse4_1 \
> > > @@ -118,17 +118,11 @@ libm-sysdep_routines += \
> > > s_truncf-sse4_1 \
> > > # libm-sysdep_routines
> > > ifeq ($(have-x86-isa-level),baseline)
> > > -sysdep_routines += \
> > > - s_modf-c \
> > > - s_modff-c \
> > > -# sysdep-routines
> > > libm-sysdep_routines += \
> > > s_ceil-c \
> > > s_ceilf-c \
> > > s_floor-c \
> > > s_floorf-c \
> > > - s_modf-c \
> > > - s_modff-c \
> > > s_nearbyint-c \
> > > s_nearbyintf-c \
> > > s_rint-c \
> > > @@ -139,6 +133,11 @@ libm-sysdep_routines += \
> > > s_truncf-c \
> > > # libm-sysdep_routines
> > > endif
> > > +
> > > +# $(sysdep_calls) functions are built both for libc and libm. While the
> > > +# libc objects have the prefix s_, the libm ones are prefixed with m_.
> > > +sysdep_routines += $(sysdep_calls)
> > > +libm-sysdep_routines += $(sysdep_calls:s_%=m_%)
> > > endif
> > >
> > > CFLAGS-e_asin-fma4.c = -mfma4
> > > @@ -159,18 +158,11 @@ CFLAGS-s_sin-avx.c = -msse2avx -DSSE2AVX
> > > CFLAGS-s_tan-avx.c = -msse2avx -DSSE2AVX
> > > CFLAGS-s_sincos-avx.c = -msse2avx -DSSE2AVX
> > >
> > > -CFLAGS-s_modf-c.c = $(no-stack-protector)
> > > -CFLAGS-s_modff-c.c = $(no-stack-protector)
> > > -
> > > -CFLAGS-s_modf-sse4_1.c = -msse4.1 -fno-builtin-modff32x \
> > > - -fno-builtin-modff64 $(no-stack-protector)
> > > -CFLAGS-s_modff-sse4_1.c = -msse4.1 -fno-builtin-modff32 \
> > > - $(no-stack-protector)
> > > +CFLAGS-s_modf-sse4_1.c = -msse4.1 -fno-builtin-modff32x -fno-builtin-modff64
> > > +CFLAGS-s_modff-sse4_1.c = -msse4.1 -fno-builtin-modff32
> > >
> > > -CFLAGS-s_modf-avx.c = -msse2avx -DSSE2AVX -fno-builtin-modff32x \
> > > - $(no-stack-protector) -fno-builtin-modff64
> > > -CFLAGS-s_modff-avx.c = -msse2avx -DSSE2AVX -fno-builtin-modff32 \
> > > - $(no-stack-protector)
> > > +CFLAGS-s_modf-avx.c = -mavx -fno-builtin-modff32x -fno-builtin-modff64
> > > +CFLAGS-s_modff-avx.c = -mavx -fno-builtin-modff32
> > > endif
> > >
> > > ifeq ($(subdir),mathvec)
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h
> > > new file mode 100644
> > > index 0000000000..071595f757
> > > --- /dev/null
> > > +++ b/sysdeps/x86_64/fpu/multiarch/ifunc-sse4_1-avx.h
> > > @@ -0,0 +1,41 @@
> > > +/* Common definition for ifunc selections optimized with SSE4.1 and AVX.
> > > + Copyright (C) 2025 Free Software Foundation, Inc.
> > > + This file is part of the GNU C Library.
> > > +
> > > + The GNU C Library is free software; you can redistribute it and/or
> > > + modify it under the terms of the GNU Lesser General Public
> > > + License as published by the Free Software Foundation; either
> > > + version 2.1 of the License, or (at your option) any later version.
> > > +
> > > + The GNU C Library is distributed in the hope that it will be useful,
> > > + but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> > > + Lesser General Public License for more details.
> > > +
> > > + You should have received a copy of the GNU Lesser General Public
> > > + License along with the GNU C Library; if not, see
> > > + <https://www.gnu.org/licenses/>. */
> > > +
> > > +#include <init-arch.h>
> > > +
> > > +extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
> > > +extern __typeof (REDIRECT_NAME) OPTIMIZE (sse41) attribute_hidden;
> > > +extern __typeof (REDIRECT_NAME) OPTIMIZE (avx) attribute_hidden;
> > > +
> > > +static inline void *
> > > +IFUNC_SELECTOR (void)
> > > +{
> > > + const struct cpu_features* cpu_features = __get_cpu_features ();
> > > +
> > > + if (CPU_FEATURE_USABLE_P (cpu_features, AVX))
> > > + return OPTIMIZE (avx);
> > > +
> > > +#if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
> > > + return OPTIMIZE (sse41);
> > > +#else
> > > + if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_1))
> > > + return OPTIMIZE (sse41);
> > > +
> > > + return OPTIMIZE (sse2);
> > > +#endif
> > > +}
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c b/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c
> > > index db32398b4a..ab4f03db0e 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c
> > > +++ b/sysdeps/x86_64/fpu/multiarch/s_modf-avx.c
> > > @@ -1 +1,3 @@
> > > +#define __modf __modf_avx
> > > +
> > > #include <sysdeps/ieee754/dbl-64/s_modf.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf-c.c b/sysdeps/x86_64/fpu/multiarch/s_modf-c.c
> > > deleted file mode 100644
> > > index 6679d322cc..0000000000
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modf-c.c
> > > +++ /dev/null
> > > @@ -1,2 +0,0 @@
> > > -#define __modf __modf_c
> > > -#include <sysdeps/ieee754/dbl-64/s_modf.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c b/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c
> > > index 6ef4c19a7e..00aa8cd736 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c
> > > +++ b/sysdeps/x86_64/fpu/multiarch/s_modf-sse4_1.c
> > > @@ -1,7 +1,3 @@
> > > -#include <sysdeps/x86/isa-level.h>
> > > -
> > > -#if MINIMUM_X86_ISA_LEVEL != SSE4_1_X86_ISA_LEVEL
> > > -# define __modf __modf_sse41
> > > -#endif
> > > +#define __modf __modf_sse41
> > >
> > > #include <sysdeps/ieee754/dbl-64/s_modf.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modf.c b/sysdeps/x86_64/fpu/multiarch/s_modf.c
> > > index d65977d69a..e365bfcef7 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modf.c
> > > +++ b/sysdeps/x86_64/fpu/multiarch/s_modf.c
> > > @@ -17,7 +17,7 @@
> > > <https://www.gnu.org/licenses/>. */
> > >
> > > #include <sysdeps/x86/isa-level.h>
> > > -#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
> > > +#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
> > > # define NO_MATH_REDIRECT
> > > # include <libm-alias-double.h>
> > >
> > > @@ -28,8 +28,14 @@
> > > # undef __modf
> > >
> > > # define SYMBOL_NAME modf
> > > -# include "ifunc-sse4_1.h"
> > > +# include "ifunc-sse4_1-avx.h"
> > >
> > > libc_ifunc_redirected (__redirect_modf, __modf, IFUNC_SELECTOR ());
> > > libm_alias_double (__modf, modf)
> > > +# if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
> > > +# define __modf __modf_sse41
> > > +# else
> > > +# define __modf __modf_sse2
> > > +# endif
> > > #endif
> > > +#include <sysdeps/ieee754/dbl-64/s_modf.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c b/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c
> > > index 804b0426b7..07cb9c1036 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c
> > > +++ b/sysdeps/x86_64/fpu/multiarch/s_modff-avx.c
> > > @@ -1 +1,3 @@
> > > +#define __modff __modff_avx
> > > +
> > > #include <sysdeps/ieee754/flt-32/s_modff.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff-c.c b/sysdeps/x86_64/fpu/multiarch/s_modff-c.c
> > > deleted file mode 100644
> > > index f54f8eacb6..0000000000
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modff-c.c
> > > +++ /dev/null
> > > @@ -1,2 +0,0 @@
> > > -#define __modff __modff_c
> > > -#include <sysdeps/ieee754/flt-32/s_modff.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c b/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c
> > > index 0437e044f3..060c5e3979 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c
> > > +++ b/sysdeps/x86_64/fpu/multiarch/s_modff-sse4_1.c
> > > @@ -1,7 +1,3 @@
> > > -#include <sysdeps/x86/isa-level.h>
> > > -
> > > -#if MINIMUM_X86_ISA_LEVEL != SSE4_1_X86_ISA_LEVEL
> > > -# define __modff __modff_sse41
> > > -#endif
> > > +#define __modff __modff_sse41
> > >
> > > #include <sysdeps/ieee754/flt-32/s_modff.c>
> > > diff --git a/sysdeps/x86_64/fpu/multiarch/s_modff.c b/sysdeps/x86_64/fpu/multiarch/s_modff.c
> > > index 89d0a32c23..a4b5429037 100644
> > > --- a/sysdeps/x86_64/fpu/multiarch/s_modff.c
> > > +++ b/sysdeps/x86_64/fpu/multiarch/s_modff.c
> > > @@ -17,7 +17,7 @@
> > > <https://www.gnu.org/licenses/>. */
> > >
> > > #include <sysdeps/x86/isa-level.h>
> > > -#if MINIMUM_X86_ISA_LEVEL < SSE4_1_X86_ISA_LEVEL
> > > +#if MINIMUM_X86_ISA_LEVEL < AVX_X86_ISA_LEVEL
> > > # define NO_MATH_REDIRECT
> > > # include <libm-alias-float.h>
> > >
> > > @@ -28,8 +28,14 @@
> > > # undef __modff
> > >
> > > # define SYMBOL_NAME modff
> > > -# include "ifunc-sse4_1.h"
> > > +# include "ifunc-sse4_1-avx.h"
> > >
> > > libc_ifunc_redirected (__redirect_modff, __modff, IFUNC_SELECTOR ());
> > > libm_alias_float (__modf, modf)
> > > +# if MINIMUM_X86_ISA_LEVEL == SSE4_1_X86_ISA_LEVEL
> > > +# define __modff __modff_sse41
> > > +# else
> > > +# define __modff __modff_sse2
> > > +# endif
> > > #endif
> > > +#include <sysdeps/ieee754/flt-32/s_modff.c>
> >
> >
>
>
> --
> Andreas K. Hüttel
> dilfridge@gentoo.org
> Gentoo Linux developer
> (council, comrel, toolchain, base-system, perl, libreoffice)
> https://wiki.gentoo.org/wiki/User:Dilfridge
--
H.J.
More information about the Libc-alpha
mailing list