People who criticize the IEEE standard typically have never read it.
Nobody forces you to use NaNs or to have partially-ordered floating-point numbers.
The default settings that have been recommended since the beginning by the standard were to not use NaNs and to have totally-ordered FP numbers.
For this choice, the invalid operation exception must not be masked.
However, it turns out that most programmers are lazy and do not want to bother to write an exception handler, so the standard libraries of C and of most other languages have chosen to mask by default this exception, which causes the generation of NaNs.
This bad default configuration in combination with the bad feature that most programming languages have only the 6 relational operators sufficient for a total order, instead of the 14 operators required for a partial order, makes necessary frequent tests for detecting whether a value is a NaN, to avoid surprising behavior in relational expressions.
I think that in most cases the extra checks for NaNs add up to much more work than writing at exception handler, so the better solution is to unmask the invalid operation exception, which makes the NaN problem go away.