diff mbox series

[committed] i386: Avoid reversing a non-trapping comparison to a trapping one [PR95169]

Message ID CAFULd4YvTV3pnxK-3HhFNXKuC1=AmOCfEaJktZ1s3g9M=zn0sQ@mail.gmail.com
State New
Headers show
Series [committed] i386: Avoid reversing a non-trapping comparison to a trapping one [PR95169] | expand

Commit Message

Uros Bizjak May 18, 2020, 3:55 p.m. UTC
gcc/ChangeLog:

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.

testsuite/ChangeLog:

2020-05-18  Uroš Bizjak  <ubizjak@gmail.com>

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

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff mbox series

Patch

diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 2865cced66c..79f827fd653 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -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
 		{
diff --git a/gcc/testsuite/gcc.target/i386/pr95169.c b/gcc/testsuite/gcc.target/i386/pr95169.c
new file mode 100644
index 00000000000..91411744228
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr95169.c
@@ -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;
+}