https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93902
--- Comment #3 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- (In reply to Andrew Pinski from comment #2) > foo3 is more complex because x86 does not have an unsigned long 64bit to > double so it has to do some more complex. But the point is that GCC shouldn't do the conversion at all. It just needs to notice that the converted value cannot be NaN. The tests can currently be simplified as follows: void foo5 (unsigned int a) { double b = a; if (b != b) bar (); } void foo6 (unsigned long a) { double b = a; if (b != b) bar (); } For foo5, one just gets a "ret", i.e. everything has been optimized. For foo6, GCC does the conversion to double, then the comparison. However, the test b != b is always false unless b is NaN; but since b comes from an integer, it cannot be NaN, i.e. foo6 is equivalent to void foo7 (unsigned long a) { double b = a; if (0) bar (); } which is fully optimized. Note that here, foo6 is fully optimized if -ffinite-math-only is provided (but foo3 still isn't). Perhaps what is missing is NaN tracking (which would be much simpler than VRP on floating-point values).