[v2,00/10] Improve rounding to interger function for C23

Message ID 20240403121150.1018799-1-adhemerval.zanella@linaro.org
Headers
Series Improve rounding to interger function for C23 |

Message

Adhemerval Zanella Netto April 3, 2024, 12:11 p.m. UTC
  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

Changes from v1:
* Updated Copyright years.

Adhemerval Zanella (10):
  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                                 | 17 ++++
 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 ++++----
 .../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 -------
 26 files changed, 892 insertions(+), 356 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
  

Comments

Joseph Myers April 3, 2024, 3:03 p.m. UTC | #1
On Wed, 3 Apr 2024, 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. 

There is testing that, in the terminology used by IEEE 754, the operations 
do not raise the exception flag (the result of default exception handling 
when the exception is signaled).  This is done through 
NO_INEXACT_EXCEPTION in libm-test-*.inc.

What is not tested is specifically quality of implementation when 
exception traps are enabled (a GNU extension outside the scope of the C 
standard).

I think that as a user-visible fix, there should be a bug filed in 
Bugzilla for this issue (that can then be marked FIXED so it goes in the 
automatically generated list of bugs fixed in the next release).
  
Adhemerval Zanella Netto April 3, 2024, 5:10 p.m. UTC | #2
On 03/04/24 12:03, Joseph Myers wrote:
> On Wed, 3 Apr 2024, 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. 
> 
> There is testing that, in the terminology used by IEEE 754, the operations 
> do not raise the exception flag (the result of default exception handling 
> when the exception is signaled).  This is done through 
> NO_INEXACT_EXCEPTION in libm-test-*.inc.
> 
> What is not tested is specifically quality of implementation when 
> exception traps are enabled (a GNU extension outside the scope of the C 
> standard).

Ack, I will add that we are now testing for exception traps.

> 
> I think that as a user-visible fix, there should be a bug filed in 
> Bugzilla for this issue (that can then be marked FIXED so it goes in the 
> automatically generated list of bugs fixed in the next release).
> 

Alright, I open bug for the x86 issues.
  
Paul Zimmermann April 4, 2024, 5:25 a.m. UTC | #3
Dear Adhemerval,

since nobody seems to have noticed, please fix the subject of this thread:
interger -> integer.

Paul