Fix lrint, llrint missing exceptions close to overflow threshold (bug 19094) [committed]
H.J. Lu
hjl.tools@gmail.com
Fri Oct 9 17:20:00 GMT 2015
On Thu, Oct 8, 2015 at 3:18 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> The dbl-64, ldbl-96 and ldbl-128 implementations of lrint and llrint
> fail to produce "invalid" exceptions in cases where the rounded result
> overflows the target type, but truncating the floating-point argument
> to the next integer towards zero does not overflow it (so in
> particular casts do not produce such exceptions). (This issue cannot
> arise for float, or for double with 64-bit target type, or for ldbl-96
> with 64-bit target type and negative arguments, because of
> insufficient precision in the floating-point type for arguments with
> the relevant property to exist. It also obviously cannot arise in
> FE_TOWARDZERO mode.)
>
> This patch fixes these problems by inserting checks for the special
> cases that can occur in each implementation, and explicitly raising
> FE_INVALID (and avoiding the cast if it might raise spurious
> FE_INEXACT, while raising FE_INEXACT explicitly in the cases where it
> is needed; unlike lround and llround, FE_INEXACT is required, not
> optional, for these functions for a within-range inexact result).
>
> The fixes are conditional on FE_INVALID or FE_INEXACT being defined.
> If any future architecture supports one but not both of those
> exceptions, the code will fail to compile and need fixing to handle
> that case (this seemed better than conditioning on both macros being
> defined, resulting in code that would compile but quietly miss
> exceptions on such a system).
>
> Tested for x86_64, x86 and mips64. Tested the ldbl-96 changes (only
> relevant for ia64, it appears) on x86_64 by removing the x86_64
> versions of lrintl / llrintl. Committed.
>
> 2015-10-08 Joseph Myers <joseph@codesourcery.com>
>
> [BZ #19094]
> * sysdeps/ieee754/dbl-64/s_lrint.c: Include <fenv.h> and
> <limits.h>.
> (__lrint) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception
> when result overflows but exception would not result from cast.
> * sysdeps/ieee754/ldbl-128/s_llrintl.c: Include <fenv.h> and
> <limits.h>.
> (__llrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception
> when result overflows but exception would not result from cast.
> * sysdeps/ieee754/ldbl-128/s_lrintl.c: Include <fenv.h> and
> <limits.h>.
> (__lrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception
> when result overflows but exception would not result from cast.
> * sysdeps/ieee754/ldbl-96/s_llrintl.c: Include <fenv.h> and
> <limits.h>.
> (__llrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception
> when result overflows but exception would not result from cast.
> * sysdeps/ieee754/ldbl-96/s_lrintl.c: Include <fenv.h> and
> <limits.h>.
> (__lrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception
> when result overflows but exception would not result from cast.
> * math/libm-test.inc (lrint_test_data): Add more tests.
> (llrint_test_data): Likewise.
>
I got
testing double (without inline functions)
Failure: lrint (0x1p31): Exception "Invalid operation" not set
Failure: lrint (0x1p32): Exception "Invalid operation" not set
Failure: lrint (0x1p33): Exception "Invalid operation" not set
Failure: lrint (-0x1p32): Exception "Invalid operation" not set
Failure: lrint (-0x1p33): Exception "Invalid operation" not set
Failure: lrint (-0x1p63): Exception "Invalid operation" not set
Failure: lrint_downward (0x1p31): Exception "Invalid operation" not set
Failure: lrint_downward (0x1p32): Exception "Invalid operation" not set
Failure: lrint_downward (0x1p33): Exception "Invalid operation" not set
Failure: lrint_downward (-0x1p32): Exception "Invalid operation" not set
Failure: lrint_downward (-0x1p33): Exception "Invalid operation" not set
Failure: lrint_downward (-0x1p63): Exception "Invalid operation" not set
Failure: lrint_towardzero (0x1p31): Exception "Invalid operation" not set
Failure: lrint_towardzero (0x1p32): Exception "Invalid operation" not set
Failure: lrint_towardzero (0x1p33): Exception "Invalid operation" not set
Failure: lrint_towardzero (-0x1p32): Exception "Invalid operation" not set
Failure: lrint_towardzero (-0x1p33): Exception "Invalid operation" not set
Failure: lrint_towardzero (-0x1p63): Exception "Invalid operation" not set
Failure: lrint_upward (0x1p31): Exception "Invalid operation" not set
Failure: lrint_upward (0x1p32): Exception "Invalid operation" not set
Failure: lrint_upward (0x1p33): Exception "Invalid operation" not set
Failure: lrint_upward (-0x1p32): Exception "Invalid operation" not set
Failure: lrint_upward (-0x1p33): Exception "Invalid operation" not set
Failure: lrint_upward (-0x1p63): Exception "Invalid operation" not set
Test suite completed:
81782 test cases plus 74758 tests for exception flags and
74758 tests for errno executed.
24 errors occurred.
on x32. Do you know why?
--
H.J.
More information about the Libc-alpha
mailing list