Behaviour differences on x86 and RISC-V on cos/sin functions

Joseph Myers joseph@codesourcery.com
Thu Dec 8 18:49:11 GMT 2022


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


More information about the Libc-alpha mailing list