llvm / llvm/llvm-project

[riscv64] `-NAN + 0 = -NAN` when performing arithmetic with `double` literals/consts instead of variables

Open
#200,030 1 comment 0 reactions 0 assignees View on GitHub
backend:RISC-V
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

Minimal repro:

```c
#include
#include
#include
#include
#include

#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);
}
```

Output:

amd64:
```
f = nan fff8000000000000
g = 0.000000 0
-NAN + 0 = nan fff8000000000000
f + g = nan fff8000000000000
```

aarch64:
```
f = nan fff8000000000000
g = 0.000000 0
-NAN + 0 = nan fff8000000000000
f + g = nan fff8000000000000
```

riscv64:
```
f = nan fff8000000000000
g = 0.000000 0
-NAN + 0 = nan fff8000000000000
f + g = nan 7ff8000000000000
```

As per 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.

Should the behaviour be different when resolving compile-time expressions rather than run-time ones?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.