Message ID | 20231228172026.2013007-1-adhemerval.zanella@linaro.org |
---|---|
Headers | show |
Series | Improve rounding to interger function for C23 | expand |
Ping. On 28/12/23 14:20, Adhemerval Zanella wrote: > As indicated by GCC documentation [1], ISO C23 does not allow that C > bindings ceil, floor, round, and trunc (in all floating point formats) > to raise > inexact exceptions (different than ISO C99/C11 where this is allowed). > > A recent MIPS patch to used some arch-specific instructions raised this > issue [1] and it was not caught because there was no proper testing. By > adding the missing tests, some implementations do indeed raise inexact > exceptions. > > The generic implementation all uses integer operation, so they are not > subject to this issue. The powerpc (for power4 and lower) and the riscv > avoid the inexact exception by disabling/enabling exceptions. The x86 > uses some arch-specific implementation for long double and on i386 (due > to the use of x87 instruction). > > Instead of adding newer symbols depending on the required standard > version, the patchset adapts the faulty ones to avoid raising the > inexact exception. The x86 version already saves/restore the floating > point status, so I think it is unlikely the patch would yield much > performance difference (I did not do any performance analysis on whether > a generic implementation would yield better performance). > > I checked on powerpc, powerpc64, aarch64, armhf, x86, and did some > regression checks on riscv. > > [1] https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fno-fp-int-builtin-inexact > [2] https://sourceware.org/pipermail/libc-alpha/2023-December/153528.html > > Adhemerval Zanella (12): > math: Reformat Makefile. > powerpc: Add missing arch flags on rounding ifunc variants > math: Add test to check if ceil raise inexact floating-point exception > math: Add test to check if floor raise inexact floating-point > exception > math: Add test to check if trunc raise inexact floating-point > exception > math: Add test to check if round raise inexact floating-point > exception > x86: Do not raise inexact exception on ceill > x86: Do not raise inexact exception on floorl > x86: Do not raise inexact exception on truncl > x86: Do not raise inexact exception on floor/floorf > i386: Do not raise inexact exception on ceil/ceilf > i386: Do not raise inexact exception on trunc/truncf > > math/Makefile | 861 ++++++++++++++---- > math/test-ceil-except-2.c | 67 ++ > math/test-ceil-except.c | 85 ++ > math/test-floor-except-2.c | 67 ++ > math/test-floor-except.c | 85 ++ > math/test-round-except-2.c | 67 ++ > math/test-round-except.c | 85 ++ > math/test-trunc-except-2.c | 67 ++ > math/test-trunc-except.c | 85 ++ > sysdeps/i386/fpu/s_ceil.S | 34 - > sysdeps/i386/fpu/s_ceil.c | 38 + > sysdeps/i386/fpu/s_ceilf.S | 34 - > sysdeps/i386/fpu/s_ceilf.c | 38 + > sysdeps/i386/fpu/s_ceill.S | 39 - > sysdeps/i386/fpu/s_floor.S | 34 - > sysdeps/i386/fpu/s_floor.c | 38 + > sysdeps/i386/fpu/s_floorf.S | 34 - > sysdeps/i386/fpu/s_floorf.c | 38 + > sysdeps/i386/fpu/s_floorl.S | 39 - > sysdeps/i386/fpu/{s_trunc.S => s_trunc.c} | 37 +- > sysdeps/i386/fpu/{s_truncf.S => s_truncf.c} | 37 +- > .../powerpc32/power4/fpu/multiarch/Makefile | 6 + > .../fpu/s_truncl.S => x86/fpu/s_ceill.c} | 38 +- > sysdeps/x86/fpu/s_floorl.c | 38 + > .../fpu/s_truncl.S => x86/fpu/s_truncl.c} | 40 +- > sysdeps/x86_64/fpu/s_ceill.S | 34 - > sysdeps/x86_64/fpu/s_floorl.S | 33 - > 27 files changed, 1583 insertions(+), 515 deletions(-) > create mode 100644 math/test-ceil-except-2.c > create mode 100644 math/test-ceil-except.c > create mode 100644 math/test-floor-except-2.c > create mode 100644 math/test-floor-except.c > create mode 100644 math/test-round-except-2.c > create mode 100644 math/test-round-except.c > create mode 100644 math/test-trunc-except-2.c > create mode 100644 math/test-trunc-except.c > delete mode 100644 sysdeps/i386/fpu/s_ceil.S > create mode 100644 sysdeps/i386/fpu/s_ceil.c > delete mode 100644 sysdeps/i386/fpu/s_ceilf.S > create mode 100644 sysdeps/i386/fpu/s_ceilf.c > delete mode 100644 sysdeps/i386/fpu/s_ceill.S > delete mode 100644 sysdeps/i386/fpu/s_floor.S > create mode 100644 sysdeps/i386/fpu/s_floor.c > delete mode 100644 sysdeps/i386/fpu/s_floorf.S > create mode 100644 sysdeps/i386/fpu/s_floorf.c > delete mode 100644 sysdeps/i386/fpu/s_floorl.S > rename sysdeps/i386/fpu/{s_trunc.S => s_trunc.c} (61%) > rename sysdeps/i386/fpu/{s_truncf.S => s_truncf.c} (61%) > rename sysdeps/{x86_64/fpu/s_truncl.S => x86/fpu/s_ceill.c} (57%) > create mode 100644 sysdeps/x86/fpu/s_floorl.c > rename sysdeps/{i386/fpu/s_truncl.S => x86/fpu/s_truncl.c} (61%) > delete mode 100644 sysdeps/x86_64/fpu/s_ceill.S > delete mode 100644 sysdeps/x86_64/fpu/s_floorl.S >