i386: Avoid reversing a non-trapping comparison to a trapping one [PR95169]
authorUros Bizjak <ubizjak@gmail.com>
Mon, 18 May 2020 15:52:14 +0000 (17:52 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Mon, 18 May 2020 15:52:14 +0000 (17:52 +0200)
gcc/ChangeLog:

PR target/95169
* config/i386/i386-expand.c (ix86_expand_int_movcc):
 Avoid reversing a non-trapping comparison to a trapping one.

testsuite/ChangeLog:

PR target/95169
* gcc.target/i386/pr95169.c: New test.

gcc/ChangeLog
gcc/config/i386/i386-expand.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr95169.c [new file with mode: 0644]

index dffe88fdcca713d869a4d3d15d727a5c2208c338..4082217fd351eaf0c0c37a2dadb27f6f80498b6e 100644 (file)
@@ -1,3 +1,9 @@
+2020-05-18  Uroš Bizjak  <ubizjak@gmail.com>
+
+       PR target/95169
+       * config/i386/i386-expand.c (ix86_expand_int_movcc):
+        Avoid reversing a non-trapping comparison to a trapping one.
+
 2020-05-18  Alex Coplan  <alex.coplan@arm.com>
 
        * config/arm/arm.c (output_move_double): Fix codegen when loading into
index 2865cced66cda96a872aee9e008b2346e1a22f96..79f827fd65348f040bb24b922aa9ce453968b883 100644 (file)
@@ -3057,11 +3057,14 @@ ix86_expand_int_movcc (rtx operands[])
            {
              gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode));
 
-             /* We may be reversing unordered compare to normal compare, that
-                is not valid in general (we may convert non-trapping condition
-                to trapping one), however on i386 we currently emit all
-                comparisons unordered.  */
-             new_code = reverse_condition_maybe_unordered (code);
+             /* We may be reversing a non-trapping
+                comparison to a trapping comparison.  */
+                 if (HONOR_NANS (cmp_mode) && flag_trapping_math
+                     && code != EQ && code != NE
+                     && code != ORDERED && code != UNORDERED)
+                   new_code = UNKNOWN;
+                 else
+                   new_code = reverse_condition_maybe_unordered (code);
            }
          else
            new_code = ix86_reverse_condition (code, cmp_mode);
@@ -3213,11 +3216,15 @@ ix86_expand_int_movcc (rtx operands[])
                {
                  gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode));
 
-                 /* We may be reversing unordered compare to normal compare,
-                    that is not valid in general (we may convert non-trapping
-                    condition to trapping one), however on i386 we currently
-                    emit all comparisons unordered.  */
-                 new_code = reverse_condition_maybe_unordered (code);
+                 /* We may be reversing a non-trapping
+                    comparison to a trapping comparison.  */
+                 if (HONOR_NANS (cmp_mode) && flag_trapping_math
+                     && code != EQ && code != NE
+                     && code != ORDERED && code != UNORDERED)
+                   new_code = UNKNOWN;
+                 else
+                   new_code = reverse_condition_maybe_unordered (code);
+
                }
              else
                {
index 89423f5dfb9967510af0e49f0a2760aa042d7ba7..320095c49ae09abbb01672a8a07a7b4e22250117 100644 (file)
@@ -1,4 +1,10 @@
+2020-05-18  Uroš Bizjak  <ubizjak@gmail.com>
+
+       PR target/95169
+       * gcc.target/i386/pr95169.c: New test.
+
 2020-05-18  Alex Coplan  <alex.coplan@arm.com>
+
        * gcc.c-torture/compile/packed-aligned-1.c: New test.
        * gcc.c-torture/execute/packed-aligned.c: New test.
 
diff --git a/gcc/testsuite/gcc.target/i386/pr95169.c b/gcc/testsuite/gcc.target/i386/pr95169.c
new file mode 100644 (file)
index 0000000..9141174
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR target/95169 */
+/* { dg-do run { target ia32 } } */
+/* { dg-options "-O0 -march=i386 -mtune=generic" } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#include <fenv.h>
+
+void
+f (double y)
+{
+  if (__builtin_expect (y == 0.0, 0))
+    __builtin_abort ();
+}
+
+int
+main (void)
+{
+  double y = __builtin_nan ("");
+
+  feclearexcept (FE_INVALID);
+
+  f (y);
+
+  if (fetestexcept (FE_INVALID))
+    __builtin_abort ();
+
+  return 0;
+}