This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fix lrint, llrint missing exceptions close to overflow threshold (bug 19094) [committed]


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]