diff mbox series

mips: Use c.ngl instead of c.ueq for LTGT [PR 91323]

Message ID f1a3ca2f92ced2c90d648135c2c37dfd532acee0.camel@mengyan1223.wang
State New
Headers show
Series mips: Use c.ngl instead of c.ueq for LTGT [PR 91323] | expand

Commit Message

Xi Ruoyao April 6, 2022, 12:38 p.m. UTC
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 mbox series

Patch

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")])
 
 ;;
 ;;  ....................