Hello! Attached patch makes FP inequality comparisons trap on qNaN. There is an old comment mentioned reversible comparisons, but middle end doesn't reverse them anymore (a couple of weeks ago, reversed comparisons were removed from i386.md):
/* ??? In order to make all comparisons reversible, we do all comparisons non-trapping when compiling for IEEE. Once gcc is able to distinguish all forms trapping and nontrapping comparisons, we can make inequality comparisons trapping again, since it results in better code when using FCOM based compares. */ FCOM compares allow FP and integer memory operands. This is also what ICC produces with -fp-model strict, so I see no reason for GCC to produce different and inferior code. 2017-10-20 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.c (ix86_fp_compare_mode): Return CCFPmode for ordered inequality comparisons even with TARGET_IEEE_FP. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. If there are no comments, I plan to commit the patch to mainline early next week. Uros.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 45a219741dbb..7ff222be9aaf 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -21500,14 +21500,35 @@ ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1) Return the appropriate mode to use. */ machine_mode -ix86_fp_compare_mode (enum rtx_code) -{ - /* ??? In order to make all comparisons reversible, we do all comparisons - non-trapping when compiling for IEEE. Once gcc is able to distinguish - all forms trapping and nontrapping comparisons, we can make inequality - comparisons trapping again, since it results in better code when using - FCOM based compares. */ - return TARGET_IEEE_FP ? CCFPUmode : CCFPmode; +ix86_fp_compare_mode (enum rtx_code code) +{ + if (!TARGET_IEEE_FP) + return CCFPmode; + + switch (code) + { + case GT: + case GE: + case LT: + case LE: + return CCFPmode; + + case EQ: + case NE: + + case LTGT: + case UNORDERED: + case ORDERED: + case UNLT: + case UNLE: + case UNGT: + case UNGE: + case UNEQ: + return CCFPUmode; + + default: + gcc_unreachable (); + } } machine_mode