The problem is found in both DMD 1.059 and 2.044 and is demonstrated by the following program - every answer should be false, but that is not the case.
import std.stdio;
T getnan(T)() { return T.nan; }
void main()
{
float f = 0.0;
double d = 0.0;
real r = 0.0;
writefln("before assigning NaN, float:%s, double:%s, real:%s", f, d, r);
f = getnan!(float)();
d = getnan!(double)();
r = getnan!(real)();
writefln(" float test, literal:%s, assign:%s, temporary:%s", (float.nan == 0), (f == 0), (getnan!(float)() == 0));
writefln("double test, literal:%s, assign:%s, temporary:%s", (double.nan == 0), (d == 0), (getnan!(double)() == 0));
writefln(" real test, literal:%s, assign:%s, temporary:%s", (real.nan == 0), (r == 0), (getnan!(real)() == 0));
}
https://github.com/D-Programming-Language/dmd/pull/760
When T is a float or double, and in memory, dmd loads it to gp registers, doubles it, then tests for zero. When it's in ST(0), dmd uses fucompp to test but the code that tests the flags is unaware of this and doesn't check the zero flag to see if it was a nan comparison.