re PR target/52451 (gcc w/i387 float generates fucom rather than fcom for floating...
authorUros Bizjak <uros@gcc.gnu.org>
Sun, 22 Oct 2017 19:04:36 +0000 (21:04 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Sun, 22 Oct 2017 19:04:36 +0000 (21:04 +0200)
PR target/52451
* config/i386/i386.c (ix86_fp_compare_mode): Return CCFPmode
for ordered inequality comparisons even with TARGET_IEEE_FP.

testsuite/ChangeLog:

PR target/52451
* gcc.dg/torture/pr52451.c: New test.

From-SVN: r253986

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr52451.c [new file with mode: 0644]

index 3ada30e..78cd3ce 100644 (file)
@@ -1,3 +1,16 @@
+2017-10-22  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/52451
+       * config/i386/i386.c (ix86_fp_compare_mode): Return CCFPmode
+       for ordered inequality comparisons even with TARGET_IEEE_FP.
+
+2017-10-22  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/82628
+       * config/i386/i386.md (cmp<dwi>_doubleword): New pattern.
+       * config/i386/i386.c (ix86_expand_branch) <case E_TImode>:
+       Expand with cmp<dwi>_doubleword.
+
 2017-10-21  Igor Tsimbalist  <igor.v.tsimbalist@intel.com>
 
        * extend.texi: Add x86 specific to 'nocf_check' attribute.
index 5abd4d8..ff0f6f8 100644 (file)
@@ -21682,14 +21682,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
index 493b361..f14930b 100644 (file)
@@ -1,4 +1,9 @@
 2017-10-22  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/52451
+       * gcc.dg/torture/pr52451.c: New test.
+
+2017-10-22  Uros Bizjak  <ubizjak@gmail.com>
            Jakub Jelinek  <jakub@redhat.com>
 
        PR target/82628
@@ -53,8 +58,7 @@
        * gcc.target/i386/cet-sjlj-3.c: Likewise.
        * gcc.target/i386/cet-switch-1.c: Likewise.
        * gcc.target/i386/cet-switch-2.c: Likewise.
-       * lib/target-supports.exp (check_effective_target_cet): New
-       proc.
+       * lib/target-supports.exp (check_effective_target_cet): New proc.
 
 2017-10-20  Jan Hubicka  <hubicka@ucw.cz>
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr52451.c b/gcc/testsuite/gcc.dg/torture/pr52451.c
new file mode 100644 (file)
index 0000000..81a3d4d
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#include <fenv.h>
+
+#define TEST_C_NOEX(CMP, S)                    \
+  r = nan##S CMP arg##S;                       \
+  if (fetestexcept (FE_INVALID))               \
+    __builtin_abort ()
+
+#define TEST_B_NOEX(FN, S)                     \
+  r = __builtin_##FN (nan##S, arg##S);         \
+  if (fetestexcept (FE_INVALID))               \
+    __builtin_abort ()
+
+#define TEST_C_EX(CMP, S)                      \
+  r = nan##S CMP arg##S;                       \
+  if (!fetestexcept (FE_INVALID))              \
+    __builtin_abort ();                                \
+  feclearexcept (FE_INVALID)
+
+#define TEST(TYPE, S)                          \
+  volatile TYPE nan##S = __builtin_nan##S ("");        \
+  volatile TYPE arg##S = 1.0##S;               \
+                                               \
+  TEST_C_NOEX (==, S);                         \
+  TEST_C_NOEX (!=, S);                         \
+                                               \
+  TEST_B_NOEX (isgreater, S);                  \
+  TEST_B_NOEX (isless, S);                     \
+  TEST_B_NOEX (isgreaterequal, S);             \
+  TEST_B_NOEX (islessequal, S);                        \
+                                               \
+  TEST_B_NOEX (islessgreater, S);              \
+  TEST_B_NOEX (isunordered, S);                        \
+                                               \
+  TEST_C_EX (>, S);                            \
+  TEST_C_EX (<, S);                            \
+  TEST_C_EX (>=, S);                           \
+  TEST_C_EX (<=, S)
+
+int
+main (void)
+{
+  volatile int r;
+
+  feclearexcept (FE_INVALID);
+
+  TEST (float, f);
+  TEST (double, );
+  TEST (long double, l);
+  
+  return 0;
+}