public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Behaviour differences on x86 and RISC-V on cos/sin functions
@ 2022-12-08 18:23 Ludovic Henry
  2022-12-08 18:49 ` Joseph Myers
  0 siblings, 1 reply; 7+ messages in thread
From: Ludovic Henry @ 2022-12-08 18:23 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1163 bytes --]

Hello,

As part of some OpenJDK work on RISC-V, I've stumbled upon a behavior
difference in cos/sin functions between x86 and RISC-V. It's not clear to
me whether the difference in behavior is acceptable, and whether it should
be handled in the OpenJDK (or other relevant libraries).

The simple test case I have which runs successfully on x86 but not RISC-V
is the following:

```
#include <stdint.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>

void main(int argc, char* argv[]) {
    int64_t bitsNaN = 0x7fff800000000000L;
    double valNaN = *((double*)&bitsNaN);

    double resD = acos(valNaN);
    int64_t res = *((int64_t*)&resD);
    if (!(res == bitsNaN)) {
        printf("expected 0x%lx but got 0x%lx\n", bitsNaN, res);
        exit(1);
    }
}
```

I can see that there are some NaN related tests in glibc already at
glibc/math/libm-test-acos.inc#L25-26 and that some are failing at
https://sourceware.org/glibc/wiki/Release/2.35#RISC-V_.28rv64imafdc.2Flp64d.29
and
https://sourceware.org/glibc/wiki/Release/2.36#RISC-V_.28rv64imafdc.2Flp64d.29.
I'm not sure exactly which test is failing though.

What do you think?

Thank you,
Ludovic

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Behaviour differences on x86 and RISC-V on cos/sin functions
  2022-12-08 18:23 Behaviour differences on x86 and RISC-V on cos/sin functions Ludovic Henry
@ 2022-12-08 18:49 ` Joseph Myers
  2022-12-08 19:24   ` Ludovic Henry
  0 siblings, 1 reply; 7+ messages in thread
From: Joseph Myers @ 2022-12-08 18:49 UTC (permalink / raw)
  To: Ludovic Henry; +Cc: libc-alpha

On Thu, 8 Dec 2022, Ludovic Henry wrote:

>     int64_t bitsNaN = 0x7fff800000000000L;
>     double valNaN = *((double*)&bitsNaN);
> 
>     double resD = acos(valNaN);
>     int64_t res = *((int64_t*)&resD);
>     if (!(res == bitsNaN)) {
>         printf("expected 0x%lx but got 0x%lx\n", bitsNaN, res);
>         exit(1);

The particular bit-pattern of a NaN resulting from a libm function is 
almost never specified in ISO C or IEEE floating point (the exceptions 
being fabs / copysign which correspond to IEEE operations that affect only 
the sign bit).  On RISC-V, instructions returning a NaN return the 
canonical quiet NaN without regard to what NaN was an input to the 
operation, so you can't expect any kind of NaN propagation there (and the 
above input is not the canonical NaN used on RISC-V so will not be the 
result of most arithmetic instructions on RISC-V).

The above is also not a safe way of inspecting the bit-pattern of a 
floating-point value (unless you're using -fno-strict-aliasing) because it 
violates standard aliasing rule; use unions or memcpy instead.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Behaviour differences on x86 and RISC-V on cos/sin functions
  2022-12-08 18:49 ` Joseph Myers
@ 2022-12-08 19:24   ` Ludovic Henry
  2022-12-08 19:58     ` Palmer Dabbelt
  2022-12-08 19:59     ` Joseph Myers
  0 siblings, 2 replies; 7+ messages in thread
From: Ludovic Henry @ 2022-12-08 19:24 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1742 bytes --]

Hi Joseph,

Thank you for the reply.

So IIUC, RISC-V behavior is expected and it should be up to the user of
libm/libc to handle the platform differences, correct?

On the value of NaN, the difference is on purpose to lead to the test
failing on RISC-V. And for inspecting the bit-pattern, I only hastily put
together to have a test case passing/failing. Thank you for the pointers
though.

I'll then figure out with the OpenJDK mailing lists what's the best way
forward.

Cheers,
Ludovic

On Thu, Dec 8, 2022 at 3:49 PM Joseph Myers <joseph@codesourcery.com> wrote:

> On Thu, 8 Dec 2022, Ludovic Henry wrote:
>
> >     int64_t bitsNaN = 0x7fff800000000000L;
> >     double valNaN = *((double*)&bitsNaN);
> >
> >     double resD = acos(valNaN);
> >     int64_t res = *((int64_t*)&resD);
> >     if (!(res == bitsNaN)) {
> >         printf("expected 0x%lx but got 0x%lx\n", bitsNaN, res);
> >         exit(1);
>
> The particular bit-pattern of a NaN resulting from a libm function is
> almost never specified in ISO C or IEEE floating point (the exceptions
> being fabs / copysign which correspond to IEEE operations that affect only
> the sign bit).  On RISC-V, instructions returning a NaN return the
> canonical quiet NaN without regard to what NaN was an input to the
> operation, so you can't expect any kind of NaN propagation there (and the
> above input is not the canonical NaN used on RISC-V so will not be the
> result of most arithmetic instructions on RISC-V).
>
> The above is also not a safe way of inspecting the bit-pattern of a
> floating-point value (unless you're using -fno-strict-aliasing) because it
> violates standard aliasing rule; use unions or memcpy instead.
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Behaviour differences on x86 and RISC-V on cos/sin functions
  2022-12-08 19:24   ` Ludovic Henry
@ 2022-12-08 19:58     ` Palmer Dabbelt
  2022-12-08 20:06       ` Joseph Myers
  2022-12-08 19:59     ` Joseph Myers
  1 sibling, 1 reply; 7+ messages in thread
From: Palmer Dabbelt @ 2022-12-08 19:58 UTC (permalink / raw)
  To: ludovic; +Cc: joseph, libc-alpha

On Thu, 08 Dec 2022 11:24:48 PST (-0800), ludovic@rivosinc.com wrote:
> Hi Joseph,
>
> Thank you for the reply.
>
> So IIUC, RISC-V behavior is expected and it should be up to the user of
> libm/libc to handle the platform differences, correct?
>
> On the value of NaN, the difference is on purpose to lead to the test
> failing on RISC-V. And for inspecting the bit-pattern, I only hastily put
> together to have a test case passing/failing. Thank you for the pointers
> though.
>
> I'll then figure out with the OpenJDK mailing lists what's the best way
> forward.
>
> Cheers,
> Ludovic
>
> On Thu, Dec 8, 2022 at 3:49 PM Joseph Myers <joseph@codesourcery.com> wrote:
>
>> On Thu, 8 Dec 2022, Ludovic Henry wrote:
>>
>> >     int64_t bitsNaN = 0x7fff800000000000L;
>> >     double valNaN = *((double*)&bitsNaN);
>> >
>> >     double resD = acos(valNaN);
>> >     int64_t res = *((int64_t*)&resD);
>> >     if (!(res == bitsNaN)) {
>> >         printf("expected 0x%lx but got 0x%lx\n", bitsNaN, res);
>> >         exit(1);
>>
>> The particular bit-pattern of a NaN resulting from a libm function is
>> almost never specified in ISO C or IEEE floating point (the exceptions
>> being fabs / copysign which correspond to IEEE operations that affect only
>> the sign bit).  On RISC-V, instructions returning a NaN return the
>> canonical quiet NaN without regard to what NaN was an input to the
>> operation, so you can't expect any kind of NaN propagation there (and the
>> above input is not the canonical NaN used on RISC-V so will not be the
>> result of most arithmetic instructions on RISC-V).

So it's OK to follow the RISC-V rules for library functions?  We don't 
have trig instructions so there's not really anything in the ISA here.  
Just following the normal rules around floating point seems 
generally sane, but I always get lost trying to read these specs...

In other words: it's safe to call this behavior not a bug?

>> The above is also not a safe way of inspecting the bit-pattern of a
>> floating-point value (unless you're using -fno-strict-aliasing) because it
>> violates standard aliasing rule; use unions or memcpy instead.
>>
>> --
>> Joseph S. Myers
>> joseph@codesourcery.com
>>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Behaviour differences on x86 and RISC-V on cos/sin functions
  2022-12-08 19:24   ` Ludovic Henry
  2022-12-08 19:58     ` Palmer Dabbelt
@ 2022-12-08 19:59     ` Joseph Myers
  1 sibling, 0 replies; 7+ messages in thread
From: Joseph Myers @ 2022-12-08 19:59 UTC (permalink / raw)
  To: Ludovic Henry; +Cc: libc-alpha

On Thu, 8 Dec 2022, Ludovic Henry wrote:

> So IIUC, RISC-V behavior is expected and it should be up to the user of
> libm/libc to handle the platform differences, correct?

Yes, if the user cares about the payload of NaN results, it's up to the 
user to handle architectures that don't propagate NaN payloads in 
arithmetic instructions.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Behaviour differences on x86 and RISC-V on cos/sin functions
  2022-12-08 19:58     ` Palmer Dabbelt
@ 2022-12-08 20:06       ` Joseph Myers
  2022-12-08 20:07         ` Palmer Dabbelt
  0 siblings, 1 reply; 7+ messages in thread
From: Joseph Myers @ 2022-12-08 20:06 UTC (permalink / raw)
  To: Palmer Dabbelt; +Cc: ludovic, libc-alpha

On Thu, 8 Dec 2022, Palmer Dabbelt wrote:

> So it's OK to follow the RISC-V rules for library functions?  We don't have

Yes (only a few functions such as fabs and copysign need to do anything in 
particular regarding NaN payloads or signs).

> In other words: it's safe to call this behavior not a bug?

Correct.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Behaviour differences on x86 and RISC-V on cos/sin functions
  2022-12-08 20:06       ` Joseph Myers
@ 2022-12-08 20:07         ` Palmer Dabbelt
  0 siblings, 0 replies; 7+ messages in thread
From: Palmer Dabbelt @ 2022-12-08 20:07 UTC (permalink / raw)
  To: joseph; +Cc: ludovic, libc-alpha

On Thu, 08 Dec 2022 12:06:59 PST (-0800), joseph@codesourcery.com wrote:
> On Thu, 8 Dec 2022, Palmer Dabbelt wrote:
>
>> So it's OK to follow the RISC-V rules for library functions?  We don't have
>
> Yes (only a few functions such as fabs and copysign need to do anything in
> particular regarding NaN payloads or signs).
>
>> In other words: it's safe to call this behavior not a bug?
>
> Correct.

Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-12-08 20:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-08 18:23 Behaviour differences on x86 and RISC-V on cos/sin functions Ludovic Henry
2022-12-08 18:49 ` Joseph Myers
2022-12-08 19:24   ` Ludovic Henry
2022-12-08 19:58     ` Palmer Dabbelt
2022-12-08 20:06       ` Joseph Myers
2022-12-08 20:07         ` Palmer Dabbelt
2022-12-08 19:59     ` Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).