TS 18661-1 defines an fesetexcept function for setting floating-point
exception flags without the side-effect of causing enabled traps to be
taken.
This patch series implements this function for glibc. The present
patch adds the fallback stub implementation, x86 and x86_64
implementations, documentation, tests and ABI baseline updates. The
remaining patches, some of them untested, add implementations for
other architectures. The implementations generally follow those of
the fesetexceptflag function.
As for fesetexceptflag, the approach taken for architectures where
setting flags causes enabled traps to be taken is to set the flags
(and potentially cause traps) rather than refusing to set the flags
and returning an error. Since ISO C and TS 18661 provide no way to
enable traps, this is formally in accordance with the standards.
The NEWS entry should be considered a placeholder, since this patch
series is intended to be followed by further such series adding other
TS 18661-1 features, so that the NEWS entry would end up looking more
like
* New <fenv.h> features from TS 18661-1:2014 are added to libm: the
fesetexcept, fetestexceptflag, fegetmode and fesetmode functions,
the femode_t type and the FE_DFL_MODE macro.
with hopefully more such entries for other features, rather than
having an entry for a single function in the end.
I believe we have consensus for adding TS 18661-1 interfaces as per
<https://sourceware.org/ml/libc-alpha/2016-06/msg00421.html>.
Tested for x86_64, x86, mips64 (hard float, and soft float to test the
fallback version), arm (hard float) and powerpc (hard float, soft
float and e500).
* math/fesetexcept.c: New file.
* sysdeps/i386/fpu/fesetexcept.c: Likewise.
* sysdeps/x86_64/fpu/fesetexcept.c: Likewise.
* math/fenv.h: Define
__GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION and include
<bits/libc-header-start.h> instead of including <features.h>.
[__GLIBC_USE (IEC_60559_BFP_EXT)] (fesetexcept): New function
declaration.
* manual/arith.texi (fesetexcept): Document function.
* math/Versions (fesetexcept): New libm symbol at version
GLIBC_2.25.
* math/Makefile (libm-support): Add fesetexcept.
(tests): Add test-fesetexcept and test-fesetexcept-traps.
* math/test-fesetexcept.c: New file.
* math/test-fesetexcept-traps.c: Likewise.
* sysdeps/nacl/libm.abilist: Update.
* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist:
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist:
Likewise.
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist:
Likewise.
* sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.
As shown by the test math/test-fexcept, the powerpc fesetexceptflag
implementation fails to clear a previously set FE_INVALID flag, when
that flag is clear in the saved exceptions and FE_INVALID is included
in the mask of flags to restore, because it fails to mask out the
sub-exceptions of FE_INVALID from the FPSCR state. This patch fixes
the masking logic accordingly.
Tested for powerpc.
[BZ #20455]
* sysdeps/powerpc/fpu/fsetexcptflg.c (__fesetexceptflag): Mask out
all FE_INVALID sub-exceptions from FPSCR when FE_INVALID specified
to be restored.
I noticed that there was no meaningful test coverage for
fegetexceptflag and fesetexceptflag (one test ensures that calls to
them compile and link, but nothing to verify they work correctly).
This patch adds tests for these functions.
fesetexceptflag is meant to set the relevant exception flag bits to
the saved state without causing enabled traps to be taken. On some
architectures, it is not possible to set exception flag bits without
causing enabled traps to occur. Such architectures need to define
EXCEPTION_SET_FORCES_TRAP to 1 in their math-tests.h, as is done in
this patch for powerpc. x86 avoids needing to define this because the
traps resulting from setting exception bits don't occur until the next
floating-point operation or fwait instruction.
Tested for x86_64, x86 and powerpc. Note that test-fexcept fails for
powerpc because of a pre-existing bug in fesetexceptflag for powerpc,
which I'll fix separately.
* math/test-fexcept-traps.c: New file.
* math/test-fexcept.c: Likewise.
* math/Makefile (tests): Add test-fexcept and test-fexcept-traps.
* sysdeps/generic/math-tests.h (EXCEPTION_SET_FORCES_TRAP): New
macro.
* sysdeps/powerpc/math-tests.h [!__NO_FPRS__]
(EXCEPTION_SET_FORCES_TRAP): Likewise.
sparc32 passes floating point values in the integer registers. VIS3
instructions gives access to the movwtos instruction to directly
transfer a value from an integer register to a floating point register.
Therefore it makes sense to provide a VIS3 version consisting in the
generic version compiled with -mvis3.
Changelog:
* math/s_fdim.c: Avoid alias renamed.
* math/s_fdimf.c: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile
[$(subdir) = math && $(have-as-vis3) = yes] (libm-sysdep_routines):
Add s_fdimf-vis3, s_fdim-vis3.
(CFLAGS-s_fdimf-vis3.c): New. Set to -Wa,-Av9d -mvis3.
(CFLAGS-s_fdim-vis3.c): Likewise.
sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim-vis3.c: New file.
sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim.c: Likewise.
The fdim and fdimf functions on sparc do not fully follow the standard
and do not set errno to ERANGE when the result overflows. Since glibc
2.24 this causes the two following tests to fail:
Failure: fdim (max_value, -max_value): errno set to 0, expected 34 (ERANGE)
Failure: fdim_upward (max_value, -max_value): errno set to 0, expected 34 (ERANGE)
It happens that using GCC with the generic C code generates very similar
code to the sparc specific implementations. Therefore this patches
remove them. Note it might still worth adding a vis3 specific version of
fdim on sparc32/sparcv9, this is done in a following patch to ease
backporting.
Changelog:
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile
[$(subdir) = math && $(have-as-vis3) = yes] (libm-sysdep_routines):
Remove s_fdimf-vis3, s_fdim-vis3.
* sysdeps/sparc/sparc32/fpu/s_fdim.S: Delete file.
* sysdeps/sparc/sparc32/fpu/s_fdimf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdim.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_fdimf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_fdim.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_fdimf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_fdim.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_fdimf.S: Likewise.
When building for sparc32/sparcv9 or sparc64, we assume that VIS
instructions are available and use them in the sparc specific assembly
code. However we do not tell GCC to use such instructions, resulting in
slightly suboptimal code.
Fix that by passing -Wa,-Av9a -mvis to GCC.
Changelog:
* sysdeps/sparc/sparc32/sparcv9/Makefile (sysdep-CFLAGS): Add -mvis.
* sysdeps/sparc/sparc64/Makefile (sysdep-CFLAGS): New. Define to
-Wa,-Av9a -mvis.
Static libraries can use the sysdep.o copy in libc.a without
a performance penalty. This results in a visible difference
if libpthread.a is relinked into a single object file (which
is needed to support libraries which check for the presence
of certain symbols to enable threading support, which generally
fails with static linking unless libpthread.a is relinked).
Presently sys/sysmacros.h is entirely defined in sysdeps. This would
mean that the deprecation logic coming up in the next patch would have
to be written twice (in generic/ and unix/sysv/linux/). To avoid that,
hoist all but the unavoidably system-dependent logic to misc/, leaving a
bits/ header behind. This also promotes the Linux-specific encoding of
dev_t, which accommodates 32-bit major and minor numbers in a 64-bit dev_t,
to generic, as glibc's dev_t is always 64 bits wide.
The former Linux implementation used inline functions to avoid evaluating
arguments more than once. After this change, all platforms use inline
functions, which means that three new symbols are added to the generic ABI.
(These symbols are in the user namespace, which is how they have always
been on Linux. They begin with "gnu_dev_", so collisions with user code
are pretty unlikely.)
New ports henceforth need only provide a bits/sysmacros.h defining
internal macros __SYSMACROS_{DECLARE,DEFINE}_{MAJOR,MINOR,MAKEDEV}.
This is only necessary if the kernel encoding is incompatible with
the now-generic encoding (for instance, it would be necessary for
FreeBSD).
While I was at it, I added a basic round-trip test for these functions.
* sysdeps/generic/sys/sysmacros.h: Delete file.
* sysdeps/unix/sysv/linux/makedev.c: Delete file.
* sysdeps/unix/sysv/linux/sys/sysmacros.h: Move file ...
* bits/sysmacros.h: ... here; this encoding is now the generic
encoding. Now defines only the following macros:
__SYSMACROS_DECLARE_MAJOR, __SYSMACROS_DEFINE_MAJOR,
__SYSMACROS_DECLARE_MINOR, __SYSMACROS_DEFINE_MINOR,
__SYSMACROS_DECLARE_MAKEDEV, __SYSMACROS_DEFINE_MAKEDEV.
* misc/sys/sysmacros.h, misc/makedev.c: New files that use
bits/sysmacros.h and the above new macros to generate the
public implementations of major, minor, and makedev.
* misc/tst-makedev.c: New test.
* include/sys/sysmacros.h: New wrapper.
* misc/Makefile (headers): Add sys/sysmacros.h, bits/sysmacros.h.
(routines): Add makedev.
(tests): Add tst-makedev.
* misc/Versions [GLIBC_2.25]: Add gnu_dev_major, gnu_dev_minor,
gnu_dev_makedev.
* posix/Makefile (headers): Remove sys/sysmacros.h.
* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Remove makedev.
* sysdeps/arm/nacl/libc.abilist: Add GLIBC_2.25,
gnu_dev_major, gnu_dev_makedev, gnu_dev_minor.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist
* sysdeps/unix/sysv/linux/alpha/libc.abilist
* sysdeps/unix/sysv/linux/arm/libc.abilist
* sysdeps/unix/sysv/linux/hppa/libc.abilist
* sysdeps/unix/sysv/linux/i386/libc.abilist
* sysdeps/unix/sysv/linux/ia64/libc.abilist
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
* sysdeps/unix/sysv/linux/microblaze/libc.abilist
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
* sysdeps/unix/sysv/linux/nios2/libc.abilist
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
* sysdeps/unix/sysv/linux/sh/libc.abilist
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
* sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist:
Add GLIBC_2.25.
There is quiet truncation to double arithmetic in several
files. I noticed them when building ldbl-128 in a
soft-fp context. This did not change any test results.
Instead of a flag which indicates the pointer can be freed, dtv_t
now includes the pointer which should be freed. Due to padding,
the size of dtv_t does not increase.
To avoid using memalign, the new allocate_dtv_entry function
allocates a sufficiently large buffer so that a sub-buffer
can be found in it which starts with an aligned pointer. Both
the aligned and original pointers are kept, the latter for calling
free later.
This patch adds the new UDP_ENCAP_GTP0 and UDP_ENCAP_GTP1U from Linux
4.7 to sysdeps/gnu/netinet/udp.h.
Tested for x86_64 and x86 (testsuite, and that installed stripped
shared libraries are unchanged by the patch).
* sysdeps/gnu/netinet/udp.h (UDP_ENCAP_GTP0): New macro.
(UDP_ENCAP_GTP1U): Likewise.
This patch adds the new PF_QIPCRTR and AF_QIPCRTR from Linux 4.7 to
sysdeps/unix/sysv/linux/bits/socket.h.
Tested for x86_64 and x86 (testsuite, and that installed stripped
shared libraries are unchanged by the patch).
* sysdeps/unix/sysv/linux/bits/socket.h (PF_QIPCRTR): New macro.
(PF_MAX): Update value.
(AF_QIPCRTR): New macro.
sparc64 passes floating point values in the floating point registers.
As the the generic ceil, floor and trunc functions use integer
instructions, it makes sense to provide a VIS3 version consisting in
the the generic version compiled with -mvis3. GCC will then use
movdtox, movxtod, movwtos and movstow instructions.
sparc32 passes the floating point values in the integer registers, so it
doesn't make sense to do the same.
Changelog:
* sysdeps/ieee754/dbl-64/s_trunc.c: Avoid alias renamed.
* sysdeps/ieee754/dbl-64/wordsize-64/s_trunc.c: Likewise.
* sysdeps/ieee754/flt-32/s_truncf.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/Makefile
[$(subdir) = math && $(have-as-vis3) = yes] (libm-sysdep_routines):
Add s_ceilf-vis3, s_ceil-vis3, s_floorf-vis3, s_floor-vis3,
s_truncf-vis3, s_trunc-vis3.
(CFLAGS-s_ceilf-vis3.c): New. Set to -Wa,-Av9d -mvis3.
(CFLAGS-s_ceil-vis3.c): Likewise.
(CFLAGS-s_floorf-vis3.c): Likewise.
(CFLAGS-s_floor-vis3.c): Likewise.
(CFLAGS-s_truncf-vis3.c): Likewise.
(CFLAGS-s_trunc-vis3.c): Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.c: New file.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf-vis3.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floor.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf-vis3.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_trunc.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_truncf-vis3.c: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_truncf.c: Likewise.
As pointer out on the mailing list, the inline assembly code in
sysdeps/powerpc/ifunc-sel.h doesn't have a list of clobbered registers
and used wrong constraints.
This patch fixes that. I verified it doesn't introduce any change in the
generated code.
Changelog:
* sysdeps/powerpc/ifunc-sel.h (ifunc_sel): Add "11", "12", "cr0" to the
clobber list. Use "i" constraint instead of "X".
(ifunc_one): Add "12" to the clobber list. Use "i" constraint instead
of "X".
On 32-bit PowerPC GCC 6 always saves the PIC register on the stack in
the prologue and adjust the stack in the epilogue. It is therefore not
possible anymore to just exit the function in the inline asm code,
otherwise it corrupts the stack pointer. This causes the following tests
to fail when using GCC 6:
FAIL: elf/ifuncmain1
FAIL: elf/ifuncmain1pic
FAIL: elf/ifuncmain1picstatic
FAIL: elf/ifuncmain1pie
FAIL: elf/ifuncmain1staticpic
FAIL: elf/ifuncmain1staticpie
FAIL: elf/ifuncmain1vis
FAIL: elf/ifuncmain1vispic
FAIL: elf/ifuncmain1vispie
FAIL: elf/ifuncmain2pic
FAIL: elf/ifuncmain2picstatic
FAIL: elf/ifuncmain3
FAIL: elf/ifuncmain4picstatic
FAIL: elf/ifuncmain5
FAIL: elf/ifuncmain5picstatic
FAIL: elf/ifuncmain5staticpic
The solution is to replace the beqlr instructions by a beq to the end
of the inline asm code. This fixes all the above failures.
ChangeLog:
* sysdeps/powerpc/ifunc-sel.h (ifunc_sel): Replace beqlr instructions
by beq instructions jumping to the end of the function.
The alpha specific version of trunc and truncf always add and subtract
0x1.0p23 or 0x1.0p52 even for big values. This causes this kind of
errors in the testsuite:
Failure: Test: trunc_towardzero (0x1p107)
Result:
is: 1.6225927682921334e+32 0x1.fffffffffffffp+106
should be: 1.6225927682921336e+32 0x1.0000000000000p+107
difference: 1.8014398509481984e+16 0x1.0000000000000p+54
ulp : 0.5000
max.ulp : 0.0000
Change this by returning the input value when its absolute value is
greater than 0x1.0p23 or 0x1.0p52. NaN have to go through the add and
subtract operations to get possibly silenced.
Finally remove the code to handle inexact exception, trunc should never
generate such an exception.
Changelog:
* sysdeps/alpha/fpu/s_trunc.c (__trunc): Return the input value
when its absolute value is greater than 0x1.0p52.
[_IEEE_FP_INEXACT] Remove.
* sysdeps/alpha/fpu/s_truncf.c (__truncf): Return the input value
when its absolute value is greater than 0x1.0p23.
[_IEEE_FP_INEXACT] Remove.
The alpha version of rint wrongly return sNaN for sNaN input. Fix that
by checking for NaN and by returning the input value added with itself
in that case.
Changelog:
* sysdeps/alpha/fpu/s_rint.c (__rint): Add argument with itself
when it is a NaN.
* sysdeps/alpha/fpu/s_rintf.c (__rintf): Likewise.
The alpha version of floor wrongly return sNaN for sNaN input. Fix that
by checking for NaN and by returning the input value added with itself
in that case.
Finally remove the code to handle inexact exception, floor should never
generate such an exception.
Changelog:
* sysdeps/alpha/fpu/s_floor.c (__floor): Add argument with itself
when it is a NaN.
[_IEEE_FP_INEXACT] Remove.
* sysdeps/alpha/fpu/s_floorf.c (__floorf): Likewise.
The alpha version of ceil wrongly return sNaN for sNaN input. Fix that
by checking for NaN and by returning the input value added with itself
in that case.
Finally remove the code to handle inexact exception, ceil should never
generate such an exception.
Changelog:
* sysdeps/alpha/fpu/s_ceil.c (__ceil): Add argument with itself
when it is a NaN.
[_IEEE_FP_INEXACT] Remove.
* sysdeps/alpha/fpu/s_ceilf.c (__ceilf): Likewise.
The ceil, floor and trunc functions on sparc do not fully follow the
standard and trigger an inexact exception when presented a value which
is not an integer. Since glibc 2.24 this causes a few tests to fail,
for instance:
testing double (without inline functions)
Failure: ceil (lit_pi): Exception "Inexact" set
Failure: ceil (-lit_pi): Exception "Inexact" set
Failure: ceil (min_subnorm_value): Exception "Inexact" set
Failure: ceil (min_value): Exception "Inexact" set
Failure: ceil (0.1): Exception "Inexact" set
Failure: ceil (0.25): Exception "Inexact" set
Failure: ceil (0.625): Exception "Inexact" set
Failure: ceil (-min_subnorm_value): Exception "Inexact" set
Failure: ceil (-min_value): Exception "Inexact" set
Failure: ceil (-0.1): Exception "Inexact" set
Failure: ceil (-0.25): Exception "Inexact" set
Failure: ceil (-0.625): Exception "Inexact" set
I tried to fix that by using the same strategy than used on other
architectures, that is by saving the FSR register at the beginning
and restoring it at the end of the function. When doing so I noticed
a comment that this operation might be very costly, so I decided to
do some benchmarks.
The benchmarks below represent the time required to run each of the
function 60 millions of times with different input value. I have done
that in the basic V9 code, the VIS2 code, and using the default C
implementation of the libc, for both sparc32 and sparc64, on a Niagara
T1 based machine and an UltraSparc IIIi. Given I don't have access to a
more recent machine), I haven't been able to test the VIS3 version. Also
it should be noted that it doesn't make sense to do this benchmark for
V8 or earlier as in that case we use the default C implementation. The
results are available in the table below, the "+ fix" version correspond
to the one saving and restoring the FSR.
Niagara T1 / sparc32
--------------------
ceilf ceil floorf floor truncf trunc
V9 19.10 22.48 19.10 22.48 16.59 19.27
V9 + fix 19.77 23.34 19.77 23.33 17.27 20.12
VIS2 16.87 19.62 16.87 19.62
VIS2 + fix 17.55 20.47 17.55 20.47
C impl 11.39 13.80 11.40 13.80 10.88 10.84
Niagara T1 / sparc64
--------------------
ceilf ceil floorf floor truncf trunc
V9 18.14 22.23 18.14 22.23 15.64 19.02
V9 + fix 18.82 23.08 18.82 23.08 16.32 19.87
VIS2 15.92 19.37 15.92 19.37
VIS2 + fix 16.59 20.22 16.59 20.22
C impl 11.39 13.60 11.39 15.36 10.88 12.65
UltraSparc IIIi / sparc32
-------------------------
ceilf ceil floorf floor truncf trunc
V9 4.81 7.09 6.61 11.64 4.91 7.05
V9 + fix 7.20 10.42 7.14 10.54 6.76 9.47
VIS2 4.81 7.03 4.76 7.13
VIS2 + fix 6.76 9.51 6.71 9.63
C impl 3.88 8.62 3.90 9.45 3.57 6.62
UltraSparc IIIi / sparc64
-------------------------
ceilf ceil floorf floor truncf trunc
V9 3.48 4.39 3.48 4.41 3.01 3.85
V9 + fix 4.76 5.90 4.76 5.90 4.86 6.26
VIS2 2.95 3.61 2.95 3.61
VIS2 + fix 4.24 5.37 4.30 7.97
C impl 3.63 4.89 3.62 6.38 3.33 4.03
The first thing that should be noted is that the C implementation is
always faster on the Niagara T1 based machine. On the UltraSparc IIIi
the float version on sparc32 is also faster.
Coming back about the fix saving and restoring the FSR, it appears
it has a big impact as expected. In that case the C implementation is
always faster than the fixed implementations.
This patch therefore removes the sparc specific implementations in
favor of the generic ones.
Changelog:
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/Makefile
[$(subdir) = math] (libm-sysdep_routines): Remove.
[$(subdir) = math && $(have-as-vis3) = yes] (libm-sysdep_routines):
Remove s_ceilf-vis3, s_ceil-vis3, s_floorf-vis3, s_floor-vis3,
s_truncf-vis3, s_trunc-vis3.
* sysdeps/sparc/sparc64/fpu/multiarch/Makefile: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_ceil-vis2.S: Delete
file.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_ceil-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_ceil.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_ceilf-vis2.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_ceilf-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_ceilf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor-vis2.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floor.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floorf-vis2.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floorf-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_floorf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_trunc-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_trunc.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_truncf-vis3.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/multiarch/s_truncf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_ceil.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_ceilf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_floor.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_floorf.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_trunc.S: Likewise.
* sysdeps/sparc/sparc32/sparcv9/fpu/s_truncf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis2.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil-vis3.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceil.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf-vis2.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf-vis3.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_ceilf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis2.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floor-vis3.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floor.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf-vis2.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf-vis3.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_floorf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_trunc-vis3.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_trunc.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_truncf-vis3.S: Likewise.
* sysdeps/sparc/sparc64/fpu/multiarch/s_truncf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_ceil.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_ceilf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_floor.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_floorf.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_trunc.S: Likewise.
* sysdeps/sparc/sparc64/fpu/s_truncf.S: Likewise.
Don't compile do_test with -mavx, -mavx nor -mavx512 since they won't run
on non-AVX machines.
[BZ #20384]
* sysdeps/x86_64/fpu/Makefile (extra-test-objs): Add
test-double-libmvec-sincos-avx-main.o,
test-double-libmvec-sincos-avx2-main.o,
test-double-libmvec-sincos-main.o,
test-float-libmvec-sincosf-avx-main.o,
test-float-libmvec-sincosf-avx2-main.o and
test-float-libmvec-sincosf-main.o.
test-float-libmvec-sincosf-avx512-main.o.
($(objpfx)test-double-libmvec-sincos): Also link with
$(objpfx)test-double-libmvec-sincos-main.o.
($(objpfx)test-double-libmvec-sincos-avx): Also link with
$(objpfx)test-double-libmvec-sincos-avx-main.o.
($(objpfx)test-double-libmvec-sincos-avx2): Also link with
$(objpfx)test-double-libmvec-sincos-avx2-main.o.
($(objpfx)test-float-libmvec-sincosf): Also link with
$(objpfx)test-float-libmvec-sincosf-main.o.
($(objpfx)test-float-libmvec-sincosf-avx): Also link with
$(objpfx)test-float-libmvec-sincosf-avx2-main.o.
[$(config-cflags-avx512) == yes] (extra-test-objs): Add
test-double-libmvec-sincos-avx512-main.o and
($(objpfx)test-double-libmvec-sincos-avx512): Also link with
$(objpfx)test-double-libmvec-sincos-avx512-main.o.
($(objpfx)test-float-libmvec-sincosf-avx512): Also link with
$(objpfx)test-float-libmvec-sincosf-avx512-main.o.
(CFLAGS-test-double-libmvec-sincos.c): Removed.
(CFLAGS-test-float-libmvec-sincosf.c): Likewise.
(CFLAGS-test-double-libmvec-sincos-main.c): New.
(CFLAGS-test-double-libmvec-sincos-avx-main.c): Likewise.
(CFLAGS-test-double-libmvec-sincos-avx2-main.c): Likewise.
(CFLAGS-test-float-libmvec-sincosf-main.c): Likewise.
(CFLAGS-test-float-libmvec-sincosf-avx-main.c): Likewise.
(CFLAGS-test-float-libmvec-sincosf-avx2-main.c): Likewise.
(CFLAGS-test-float-libmvec-sincosf-avx512-main.c): Likewise.
(CFLAGS-test-double-libmvec-sincos-avx.c): Set to -DREQUIRE_AVX.
(CFLAGS-test-float-libmvec-sincosf-avx.c ): Likewise.
(CFLAGS-test-double-libmvec-sincos-avx2.c): Set to
-DREQUIRE_AVX2.
(CFLAGS-test-float-libmvec-sincosf-avx2.c ): Likewise.
(CFLAGS-test-double-libmvec-sincos-avx512.c): Set to
-DREQUIRE_AVX512F.
(CFLAGS-test-float-libmvec-sincosf-avx512.c): Likewise.
* sysdeps/x86_64/fpu/test-double-libmvec-sincos.c: Rewritten.
* sysdeps/x86_64/fpu/test-float-libmvec-sincosf.c: Likewise.
* sysdeps/x86_64/fpu/test-double-libmvec-sincos-avx-main.c: New
file.
* sysdeps/x86_64/fpu/test-double-libmvec-sincos-avx2-main.c:
Likewise.
* sysdeps/x86_64/fpu/test-double-libmvec-sincos-avx512-main.c:
Likewise.
* sysdeps/x86_64/fpu/test-double-libmvec-sincos-main.c:
Likewise.
* sysdeps/x86_64/fpu/test-float-libmvec-sincosf-avx-main.c:
Likewise.
* sysdeps/x86_64/fpu/test-float-libmvec-sincosf-avx2-main.c:
Likewise.
* sysdeps/x86_64/fpu/test-float-libmvec-sincosf-avx512-main.c:
Likewise.
* sysdeps/x86_64/fpu/test-float-libmvec-sincosf-main.c:
Likewise.
This partly reverts commit f8238ae3c7
that regenerated the ulps, to make the max ulps good for gcc-5,
gcc-6 and gcc-trunk as well.
* sysdeps/aarch64/libm-test-ulps: Updated.
If the default memcpy variant is called with a length of >1MB on 31bit,
r13 is clobbered as the algorithm is switching to mvcle. The mvcle code
returns without restoring r13. All other cases are restoring r13.
If memcpy is called from outside libc the ifunc resolver will only select
this variant if running on machines older than z10.
Otherwise or if memcpy is called from inside libc, this default memcpy
variant is called.
The testcase timezone/tst-tzset is triggering this issue in some combinations
of gcc versions and optimization levels.
This bug was introduced in commit 04bb21ac93
and thus is a regression compared to former glibc 2.23 release.
This patch removes the usage of r13 at all. Thus it is not saved and restored.
The base address for execute-instruction is now stored in r5 which is obtained
after r5 is not needed anymore as 256byte block counter.
ChangeLog:
* sysdeps/s390/s390-32/memcpy.S (memcpy): Eliminate the usage
of r13 as it is not restored in mvcle case.
If a function passes in a variable named "ret", the code will miscompile
when it declares a local ret variable. In some cases, it's even a build
failure like so:
../sysdeps/unix/sysv/linux/spawni.c: In function '__spawni_child':
../sysdeps/unix/sysv/linux/spawni.c:289:5: error: address of register variable 'ret' requested
while (write_not_cancel (p, &ret, sizeof ret) < 0)
Compile i386 rtld-*.os with -mno-sse -mno-mmx -mfpmath=387 so that no
code in ld.so uses mm/xmm/ymm/zmm registers on i386 since the first 3
mm/xmm/ymm/zmm registers are used to pass vector parameters which must
be preserved.
* sysdeps/i386/Makefile (rtld-CFLAGS): New.
[subdir == elf] (CFLAGS-.os): Replace -mno-sse -mno-mmx
-mfpmath=387 with $(rtld-CFLAGS).
[subdir != elf] (CFLAGS-.os): Compile rtld-*.os with
$(rtld-CFLAGS).
During the sincos consolidation I made two mistakes, one was a logical
error due to which cos(0x1.8475e5afd4481p+0) returned
sin(0x1.8475e5afd4481p+0) instead.
The second issue was an error in negating inputs for the correct
quadrants for sine. I could not find a suitable test case for this
despite running a program to search for such an input for a couple of
hours.
Following patch fixes both issues. Tested on x86_64. Thanks to Matt
Clay for identifying the issue.
[BZ #20357]
* sysdeps/ieee754/dbl-64/s_sin.c (sloww): Fix up condition
to call __mpsin/__mpcos and to negate values.
* math/auto-libm-test-in: Add test.
* math/auto-libm-test-out: Regenerate.
This patch changes both the nptl and libc Linux raise implementation
to avoid the issues described in BZ#15368. The strategy used is
summarized in bug report first comment:
1. Block all signals (including internal NPTL ones);
2. Get pid and tid directly from syscall (not relying on cached
values);
3. Call tgkill;
4. Restore old signal mask.
Tested on x86_64 and i686.
[BZ #15368]
* sysdeps/unix/sysv/linux/nptl-signals.h
(__nptl_clear_internal_signals): New function.
(__libc_signal_block_all): Likewise.
(__libc_signal_block_app): Likewise.
(__libc_signal_restore_set): Likewise.
* sysdeps/unix/sysv/linux/pt-raise.c (raise): Use Linux raise.c
implementation.
* sysdeps/unix/sysv/linux/raise.c (raise): Reimplement to not use
the cached pid/tid value in pthread structure.
64-bit off_t in pread64, preadv, pwrite64 and pwritev syscalls is passed
in one 64-bit register for both x32 and x86-64. Since the inline
asm statement only passes long, which is 32-bit for x32, in registers,
64-bit off_t is truncated to 32-bit on x32. Since __ASSUME_PREADV and
__ASSUME_PWRITEV are defined unconditionally, these syscalls can be
implemented in syscalls.list to pass 64-bit off_t in one 64-bit register.
Tested on x86-64 and x32 with off_t > 4GB on pread64/pwrite64 and
preadv64/pwritev64.
[BZ #20348]
* sysdeps/unix/sysv/linux/x86_64/syscalls.list: Add pread64,
preadv64, pwrite64 and pwritev64.
Since _dl_tlsdesc_dynamic is called via PLT, we need to add 8 bytes for
push in the PLT entry to align the stack.
[BZ #20309]
* configure.ac (have-mtls-dialect-gnu2): Set to yes if
-mtls-dialect=gnu2 works.
* configure: Regenerated.
* elf/Makefile [have-mtls-dialect-gnu2 = yes]
(tests): Add tst-gnu2-tls1.
(modules-names): Add tst-gnu2-tls1mod.
($(objpfx)tst-gnu2-tls1): New.
(tst-gnu2-tls1mod.so-no-z-defs): Likewise.
(CFLAGS-tst-gnu2-tls1mod.c): Likewise.
* elf/tst-gnu2-tls1.c: New file.
* elf/tst-gnu2-tls1mod.c: Likewise.
* sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Add 8
bytes for push in the PLT entry to align the stack.
Define LO_HI_LONG to skip pos_h since it is ignored by kernel:
static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
{
#define HALF_LONG_BITS (BITS_PER_LONG / 2)
return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
}
where size of loff_t == size of long.
[BZ #20349]
* sysdeps/unix/sysv/linux/x86_64/sysdep.h (LO_HI_LONG): New.
AArch64 uses HWCAP bits but they are not defined in sys/auxv.h.
This patch adds a copy of the linux v4.6 arm64 uapi asm/hwcap.h
definitions.
* sysdeps/unix/sysv/linux/aarch64/bits/hwcap.h: New.
When glibc is built with --enable-profile, the ENTRY of
asm functions includes CALL_MCOUNT for profiling.
(matters for binaries static linked against libc_p.a.)
CALL_MCOUNT did not save/restore argument registers
around the _mcount call so it clobbered them.
(it is enough to only save/restore the arguments passed
to a given asm function, but that would be too many asm
changes so it is simpler to always save all argument
registers in this macro.)
float args are not saved: mcount does not clobber the
float regs and currently no asm function takes float
arguments anyway.
[BZ #18707]
* sysdeps/aarch64/Makefile (CFLAGS-mcount.c): Add -mgeneral-regs-only.
* sysdeps/aarch64/sysdep.h (CALL_MCOUNT): Save argument registers.
The p{read,write}v{64} consolidation patch [1] added a wrong guard
for LO_HI_LONG definition. It currently uses both
'__WORDSIZE == 64' and 'defined __ASSUME_WORDSIZE64_ILP32' to set
the value to be passed in one argument, otherwise it will be split
in two.
However it fails on MIPS64n32 where syscalls n32 uses the compat
implementation in the kernel meaning the off_t arguments are passed
in two separate registers.
GLIBC already defines a macro for such cases (__OFF_T_MATCHES_OFF64_T),
so this patch uses it instead.
Checked on x86_64, i686, x32, aarch64, armhf, and s390.
* sysdeps/unix/sysv/linux/sysdep.h
[__WORDSIZE == 64 || __ASSUME_WORDSIZE64_ILP32] (LO_HI_LONG): Remove
guards.
* misc/tst-preadvwritev-common.c: New file.
* misc/tst-preadvwritev.c: Use tst-preadvwritev-common.c.
* misc/tst-preadvwritev64.c: Use tst-preadwritev-common.c and add
a check for files larger than 2GB.
[1] 4751bbe2ad
This patch removes the __ASSUME_OFF_DIFF_OFF64 define introduced in
p{read,write} consolidation patch. This define was added based on
the idea 32 bits ports would continue to follow previous off{64}_t
definition where off_t size differs from off64_t one.
However, with recent AArch64/ILP32 patch submission and also with
discussion for RISCV kernel interface, 32 bits ports now may aim
to use off_t and off64_t with the same size as 64 bits.
So current assumption for both p{read,write} and p{read,write}v
are not compatible with new type definition. This patch now makes
the syscall wrappers to only depend on __OFF_T_MATCHES_OFF64_T to
define the default and 64-suffix variant, as follow:
<function>.c
#ifndef __OFF_T_MATCHES_OFF64_T
/* build <function> */
#endif
and
<function>64.c
/* build <function>64 */
#ifdef __OFF_T_MATCHES_OFF64_T
weak_alias (fallocate64, fallocate)
#endif
Tested on x86_64, i686, x32, and armhf.
* sysdeps/unix/sysv/linux/mips/kernel-features.h
(__ASSUME_OFF_DIFF_OFF64): Remove define.
* sysdeps/unix/sysv/linux/pread.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (pread): Replace by
__OFF_T_MATCHES_OFF64_T.
* sysdeps/unix/sysv/linux/pread64.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (pread64): Likewise.
* sysdeps/unix/sysv/linux/preadv.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (preadv): Likewise.
* sysdeps/unix/sysv/linux/preadv64.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (preadv64): Likewise.
* sysdeps/unix/sysv/linux/pwrite.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (pwrite): Likewise.
* sysdeps/unix/sysv/linux/pwrite64.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (pwrite64): Likewise.
* sysdeps/unix/sysv/linux/pwritev.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (pwritev): Likewise.
* sysdeps/unix/sysv/linux/pwritev64.c
[__WORDSIZE != 64 || __ASSUME_OFF_DIFF_OFF64] (pwritev64): Likewise.
The previous uses of this symbol were all in wordsize-32 code.
In commit eeddfa91cb ("Consolidate off_t/off64_t syscall
argument passing") it was expanded to be used in pread/pwrite.
Accordingly, we only define it in 32-bit compilation modes now.
Both tilepro and tilegx32 follow this convention for the
kernel ABI. tilegx64 follows it for passing 128-bit values,
but there are no such ABIs in the kernel.