This patch refactors and fixes an issue where arm_mve_dlstp_check_dec_counter
was making an assumption about the form of what a candidate for a dec_insn.

It also makes sure that if it does not initially encounter a 'set' in such a
form it tries to find another set that could be the right one.

gcc/ChangeLog:

        * config/arm/arm.cc (check_dec_insn): New helper function containing
        code hoisted from...
        (arm_mve_dlstp_check_dec_counter): ... here. Use check_dec_insn to
        check the validity of the candidate dec_insn.

gcc/testsuite/ChangeLog:

        * gcc.targer/arm/mve/dlstp-loop-form.c: New test.


Regression tested mve.exp for arm-none-eabi with -mcpu=cortex-m85.

OK for trunk?

Kind regards,
Andre Vieira
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 
92cd168e65937ef7350477464e8b0becf85bceed..e145a69ed4c6c5b925c1dc2bc25b98f2a1af5849
 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -35214,6 +35214,30 @@ arm_mve_dlstp_check_inc_counter (loop *loop, rtx_insn* 
vctp_insn,
   return vctp_insn;
 }
 
+/* Helper function to 'arm_mve_dlstp_check_dec_counter' to make sure DEC_INSN
+   is of the expected form:
+   (set (reg a) (plus (reg a) (const_int)))
+   where (reg a) is the same as CONDCOUNT.  */
+
+static bool
+check_dec_insn (rtx_insn *dec_insn, rtx condcount)
+{
+  if (!NONDEBUG_INSN_P (dec_insn))
+    return false;
+  rtx dec_set = single_set (dec_insn);
+  if (!dec_set
+      || !REG_P (SET_DEST (dec_set))
+      || GET_CODE (SET_SRC (dec_set)) != PLUS
+      || !REG_P (XEXP (SET_SRC (dec_set), 0))
+      || !CONST_INT_P (XEXP (SET_SRC (dec_set), 1))
+      || REGNO (SET_DEST (dec_set))
+         != REGNO (XEXP (SET_SRC (dec_set), 0))
+      || REGNO (SET_DEST (dec_set)) != REGNO (condcount))
+    return false;
+
+  return true;
+}
+
 /* Helper function to `arm_mve_loop_valid_for_dlstp`.  In the case of a
    counter that is decrementing, ensure that it is decrementing by the
    right amount in each iteration and that the target condition is what
@@ -35232,30 +35256,19 @@ arm_mve_dlstp_check_dec_counter (loop *loop, 
rtx_insn* vctp_insn,
      modified.  */
   rtx_insn *dec_insn = BB_END (loop->latch);
   /* If not in the loop latch, try to find the decrement in the loop header.  
*/
-  if (!NONDEBUG_INSN_P (dec_insn))
+  if (!check_dec_insn(dec_insn, condcount))
   {
     df_ref temp = df_bb_regno_only_def_find (loop->header, REGNO (condcount));
     /* If we haven't been able to find the decrement, bail out.  */
     if (!temp)
       return NULL;
     dec_insn = DF_REF_INSN (temp);
-  }
 
-  rtx dec_set = single_set (dec_insn);
-
-  /* Next, ensure that it is a PLUS of the form:
-     (set (reg a) (plus (reg a) (const_int)))
-     where (reg a) is the same as condcount.  */
-  if (!dec_set
-      || !REG_P (SET_DEST (dec_set))
-      || !REG_P (XEXP (SET_SRC (dec_set), 0))
-      || !CONST_INT_P (XEXP (SET_SRC (dec_set), 1))
-      || REGNO (SET_DEST (dec_set))
-         != REGNO (XEXP (SET_SRC (dec_set), 0))
-      || REGNO (SET_DEST (dec_set)) != REGNO (condcount))
-    return NULL;
+    if (!check_dec_insn(dec_insn, condcount))
+      return NULL;
+  }
 
-  decrementnum = INTVAL (XEXP (SET_SRC (dec_set), 1));
+  decrementnum = INTVAL (XEXP (SET_SRC (single_set (dec_insn)), 1));
 
   /* This decrementnum is the number of lanes/elements it decrements from the
      remaining number of lanes/elements to process in the loop, for this reason
diff --git a/gcc/testsuite/gcc.target/arm/mve/dlstp-loop-form.c 
b/gcc/testsuite/gcc.target/arm/mve/dlstp-loop-form.c
new file mode 100644
index 
0000000000000000000000000000000000000000..20c9dcd2984ba75701d853bcbba10caf12b5f2bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/mve/dlstp-loop-form.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_1m_mve_ok } */
+/* { dg-options "-Ofast" } */
+/* { dg-add-options arm_v8_1m_mve } */
+#pragma GCC arm "arm_mve_types.h"
+#pragma GCC arm "arm_mve.h" false
+typedef __attribute__((aligned(2))) float16x8_t e;
+mve_pred16_t c(long d) { return __builtin_mve_vctp16qv8bi(d); }
+int f();
+void n() {
+  int g, h, *i, j;
+  mve_pred16_t k;
+  e acc;
+  e l;
+  e m;
+  for (;;) {
+    j = g;
+    acc[g];
+    for (; h < g; h += 8) {
+      k = c(j);
+      acc = vfmsq_m(acc, l, m, k);
+      j -= 8;
+    }
+    i[g] = f(acc);
+  }
+}
+

Reply via email to