[i386] : Fix PR 91323, LTGT rtx produces UCOMISS instead of COMISS

Message ID CAFULd4bGs_GaybCovSb24o4wFhdVHXXY9ABZ=j6jk6-Ras5YsQ@mail.gmail.com
State New
Headers show
Series
  • [i386] : Fix PR 91323, LTGT rtx produces UCOMISS instead of COMISS
Related show

Commit Message

Uros Bizjak Aug. 2, 2019, 10:03 a.m.
Attached patch fixes LTGT to trap on unordered operands. The patch
also adds a testcase that will enforce traps for LTGT on other
targets.

2019-08-02  UroŇ° Bizjak  <ubizjak@gmail.com>

    PR target/91323
    * config/i386/i386-expand.c (ix86_unordered_fp_compare) <case LTGT>:
    Return false.

testsuite/ChangeLog:

2019-08-02  UroŇ° Bizjak  <ubizjak@gmail.com>

    PR target/91323
    * gcc.dg/torture/pr91323.c: New test.

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

Committed to mainline SVN.

Uros.

Patch

Index: config/i386/i386-expand.c
===================================================================
--- config/i386/i386-expand.c	(revision 273981)
+++ config/i386/i386-expand.c	(working copy)
@@ -2286,16 +2286,16 @@  ix86_unordered_fp_compare (enum rtx_code code)
 
   switch (code)
     {
+    case LT:
+    case LE:
     case GT:
     case GE:
-    case LT:
-    case LE:
+    case LTGT:
       return false;
 
     case EQ:
     case NE:
 
-    case LTGT:
     case UNORDERED:
     case ORDERED:
     case UNLT:
Index: testsuite/gcc.dg/torture/pr91323.c
===================================================================
--- testsuite/gcc.dg/torture/pr91323.c	(nonexistent)
+++ testsuite/gcc.dg/torture/pr91323.c	(working copy)
@@ -0,0 +1,51 @@ 
+/* { dg-do run } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#include <fenv.h>
+
+int
+__attribute__ ((noinline, noclone))
+f1 (float a, float b)
+{
+  return __builtin_isless (a, b) || __builtin_isgreater (a, b);
+}
+
+int
+__attribute__ ((noinline, noclone))
+f2 (float a, float b)
+{
+  return __builtin_islessgreater (a, b);
+}
+
+int
+__attribute__ ((noinline, noclone))
+f3 (float a, float b)
+{
+  return a < b || a > b;
+}
+
+int
+main (void)
+{
+  volatile int r;
+
+  float nanf = __builtin_nanf ("");
+  float argf = 1.0f;
+
+  feclearexcept (FE_INVALID);
+
+  r = f1 (nanf, argf);
+  if (fetestexcept (FE_INVALID))
+    __builtin_abort ();
+
+  r = f2 (nanf, argf);
+  if (fetestexcept (FE_INVALID))
+    __builtin_abort ();
+
+  r = f3 (nanf, argf);
+  if (!fetestexcept (FE_INVALID))
+    __builtin_abort ();
+
+  return 0;
+}