`-nan + 0 = +nan` on riscv64
As stated in the riscv reference here: https://docs.riscv.org/reference/isa/unpriv/f-st-ext.html#21-1-3-nan-generation-and-propagation
> Except when otherwise stated, if the result of a floating-point operation is NaN, it is the canonical NaN. The canonical NaN has a positive sign and all significand bits clear except the MSB, a.k.a. the quiet bit.
With relevance to awk, since awk uses `double`-precision floats for numbers, canonical NaN translates to `+nan = 7ff8000000000000`.
In https://github.com/onetrueawk/awk/blob/5739fd79bcfc75ba7526773d0cf634521f8aca3c/bugs-fixed/inf-nan-torture.in#L1, line 4 asserts that `-nan + 0 = -nan`, but this is NOT true on riscv64.
Here's a minimal repro that shows the issue on both gcc and clang on riscv64:
```c
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#define myprint(d) do { \
double _d = (d); \
uint64_t _u; \
memcpy(&_u, &_d, sizeof(_d)); \
printf("%s = %f %" PRIx64 "\n", #d, _d, _u); \
} while (0)
int main(void)
{
double f = -NAN;
double g = 0;
myprint(f);
myprint(g);
myprint(-NAN + 0);
myprint(f + g);
}
```
Thus, that testcase is not portable. Downstream, we can see the test failure on FreeBSD in CI here: https://ci.freebsd.org/job/FreeBSD-main-riscv64-test/16606/testReport/usr.bin.awk.bugs-fixed/bug_fix_test/inf_nan_torture/
2 条评论