Description
Compile and run the following C program:
#include <stdio.h>
#include <stdint.h>
double add0(double x) {
return x+0;
}
int main(int argc, char *argv[]) {
double snan64;
*(uint64_t*)&snan64 = 0x7ff0000000000001;
printf("snan64: %llx\n", *(uint64_t*)&snan64);
double x = add0(snan64);
printf(" add0: %llx\n", *(uint64_t*)&x);
}
On the linux-mips64le-mengzhuo builders, it prints
snan64: 7ff0000000000001
add0: 7ff8000000000001
On the linux-mips64le-rtrk builders, it prints
snan64: 7ff0000000000001
add0: 7ff0000000000001
Note that on the mengzhuo builder, the quiet bit gets set, whereas on the rtrk builder it does not.
This seems like a strange inconsistency. The assembly code for add0
is the same on both platforms.
It seems strange that the rtrk builder doesn't convert the NaN from signaling to quiet. add0
quiets the NaN for all the other Go platforms we support (amd64, powerpc, etc.). There are also strange inconsistencies with how it handles float32 <-> float64 conversions of signaling NaNs, which is how I first noticed this (#36399).
Is this expected behavor? Is this allowed by the spec? Might it be a bug in the rtrk builder? Is there some floating-point-signal-interrupt-control-word thingy we might need to set?