From: Karl Meakin <[email protected]>

Apply the same fix from bc11cbff9e648fdda2798bfa2d7151d5cd164b87
("aarch64: Fix condition accepted by mov<ALLI>cc") to `MOV<GPF>cc`.
Fixes ICEs when compiling code such as `cmpbr-4.c` with `+cmpbr`.

gcc/ChangeLog:

        * config/aarch64/aarch64.md(mov<GPF>cc): Accept MODE_CC
        conditions directly; reject QI/HImode conditions.

gcc/testsuite/ChangeLog:

        * gcc.target/aarch64/cmpbr-4.c: New test.
---
 gcc/config/aarch64/aarch64.md              | 48 +++++++++++++++-------
 gcc/testsuite/gcc.target/aarch64/cmpbr-4.c | 12 ++++++
 2 files changed, 45 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/cmpbr-4.c

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 98c65a74c8e..e2b8d5d3af9 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -4829,15 +4829,21 @@
 			  (match_operand:GPF 3 "register_operand")))]
   ""
   {
-    rtx ccreg;
     enum rtx_code code = GET_CODE (operands[1]);
-
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
-				  XEXP (operands[1], 1));
-    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+    rtx ccreg = XEXP (operands[1], 0);
+    enum machine_mode ccmode = GET_MODE (ccreg);
+    if (GET_MODE_CLASS (ccmode) == MODE_CC)
+      gcc_assert (XEXP (operands[1], 1) == const0_rtx);
+    else if (ccmode == QImode || ccmode == HImode)
+      FAIL;
+    else
+      {
+	ccreg = aarch64_gen_compare_reg (code, ccreg, XEXP (operands[1], 1));
+	operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+      }
   }
 )
 
@@ -4848,15 +4854,21 @@
 			  (match_operand:GPF 3 "register_operand")))]
   ""
   {
-    rtx ccreg;
     enum rtx_code code = GET_CODE (operands[1]);
-
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
-				  XEXP (operands[1], 1));
-    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+    rtx ccreg = XEXP (operands[1], 0);
+    enum machine_mode ccmode = GET_MODE (ccreg);
+    if (GET_MODE_CLASS (ccmode) == MODE_CC)
+      gcc_assert (XEXP (operands[1], 1) == const0_rtx);
+    else if (ccmode == QImode || ccmode == HImode)
+      FAIL;
+    else
+      {
+	ccreg = aarch64_gen_compare_reg (code, ccreg, XEXP (operands[1], 1));
+	operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+      }
   }
 )
 
@@ -4867,15 +4879,21 @@
 			  (match_operand:GPI 3 "register_operand")))]
   ""
   {
-    rtx ccreg;
     enum rtx_code code = GET_CODE (operands[1]);
-
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
-				      XEXP (operands[1], 1));
-    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+    rtx ccreg = XEXP (operands[1], 0);
+    enum machine_mode ccmode = GET_MODE (ccreg);
+    if (GET_MODE_CLASS (ccmode) == MODE_CC)
+      gcc_assert (XEXP (operands[1], 1) == const0_rtx);
+    else if (ccmode == QImode || ccmode == HImode)
+      FAIL;
+    else
+      {
+	ccreg = aarch64_gen_compare_reg (code, ccreg, XEXP (operands[1], 1));
+	operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+      }
   }
 )
 
diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr-4.c b/gcc/testsuite/gcc.target/aarch64/cmpbr-4.c
new file mode 100644
index 00000000000..e266ce1cc77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cmpbr-4.c
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+#pragma GCC target "+cmpbr"
+
+typedef unsigned short Quantum;
+
+double MagickMax(double x, double y) { return x > y ? x : y; }
+
+void ConvertRGBToHCL(Quantum red, Quantum green) {
+    if (red == MagickMax(red, green)) __builtin_abort();
+}

Reply via email to