Fixes gcc.dg/torture/pr91323.c fail for MIPS.  Ok for trunk?

LTGT should trap for unordered operands (see discussion in bugzilla),
but c.ueq does not trap for qNaN.  Use c.ngl as it handles non-NaN
operands like c.ueq, but traps for qNaN as we want for LTGT.

gcc/
        PR target/91323
        * config/mips/mips.md (sngl_<mode>_using_cc): New insn pattern
        for c.ngl.{f,d}.
        * config/mips/mips.cc (mips_emit_compare): Use c.ngl.{f,d} for
        LTGT.
---
 gcc/config/mips/mips.cc | 38 +++++++++++++++++++++++++++++++++-----
 gcc/config/mips/mips.md | 10 ++++++++++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 5010f99f761..77675a57a01 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -5625,6 +5625,7 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx 
*op1, bool need_eq_ne_p)
     }
   else
     {
+      bool need_ngl = false;
       enum rtx_code cmp_code;
 
       /* Floating-point tests use a separate C.cond.fmt or CMP.cond.fmt
@@ -5643,10 +5644,20 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx 
*op1, bool need_eq_ne_p)
        }
       else
        {
-         /* Three FP conditions cannot be implemented by reversing the
-            operands for C.cond.fmt, instead a reversed condition code is
-            required and a test for false.  */
-         *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE;
+         /* We'll need a special case.  LTGT is not an unordered compare
+            (PR 91323) so we can't simply use !UNEQ for it.  MIPS has
+            "ngl" (Not Greater than or Less than) condition as a perfect
+            opposite of LTGT, but we don't have an rtx_code for it.  */
+         if (cmp_code == LTGT)
+           {
+             need_ngl = true;
+             *code = EQ;
+           }
+         else
+           /* Three FP conditions cannot be implemented by reversing the
+              operands for C.cond.fmt, instead a reversed condition code
+              is required and a test for false.  */
+           *code = mips_reversed_fp_cond (&cmp_code) ? EQ : NE;
          if (ISA_HAS_8CC)
            *op0 = mips_allocate_fcc (CCmode);
          else
@@ -5654,7 +5665,24 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx 
*op1, bool need_eq_ne_p)
        }
 
       *op1 = const0_rtx;
-      mips_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1);
+      if (need_ngl)
+       {
+         rtx insn;
+         switch (GET_MODE (cmp_op0))
+           {
+             case SFmode:
+               insn = gen_sngl_sf_using_cc (*op0, cmp_op0, cmp_op1);
+               break;
+             case DFmode:
+               insn = gen_sngl_df_using_cc (*op0, cmp_op0, cmp_op1);
+               break;
+             default:
+               gcc_unreachable ();
+           }
+         emit_insn(insn);
+       }
+      else
+       mips_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1);
     }
 }
 
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index e0f0a582732..47405f03d7a 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -6293,6 +6293,16 @@ (define_insn "s<code>_<SCALARF:mode>_using_<FPCC:mode>"
   "<fpcmp>.<swapped_fcond>.<fmt>\t%Z0%2,%1"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "FPSW")])
+
+(define_insn "sngl_<SCALARF:mode>_using_cc"
+  [(set (match_operand:CC 0 "register_operand" "=z")
+       (eq:CC (const_int 0)
+              (ltgt:CC (match_operand:SCALARF 1 "register_operand" "f")
+                       (match_operand:SCALARF 2 "register_operand" "f"))))]
+  "!ISA_HAS_CCF"
+  "c.ngl.<fmt>\t%Z0%1,%2"
+  [(set_attr "type" "fcmp")
+   (set_attr "mode" "FPSW")])
 
 ;;
 ;;  ....................
-- 
2.35.1


Reply via email to