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` and `cmpbr-5.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.target/aarch64/cmpbr-5.c: New test.
---
gcc/config/aarch64/aarch64.md | 48 +++++++++++++++-------
gcc/testsuite/gcc.target/aarch64/cmpbr-4.c | 12 ++++++
gcc/testsuite/gcc.target/aarch64/cmpbr-5.c | 13 ++++++
3 files changed, 58 insertions(+), 15 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/cmpbr-4.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/cmpbr-5.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();
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/cmpbr-5.c b/gcc/testsuite/gcc.target/aarch64/cmpbr-5.c
new file mode 100644
index 00000000000..049e8c107f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cmpbr-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O1" } */
+#pragma GCC target "+cmpbr"
+typedef unsigned short us;
+__GIMPLE double
+f (us x, us y, double a, double b)
+{
+ bool c;
+ double d;
+ c = x == y;
+ d = c ? a : b;
+ return d;
+}