Sorry for the delay, some other work popped up in between and this had some latent issues. They should all be addressed now in this new patch.

When not dealing with the special armv8.1-m.main conditional instructions case make sure it uses the default_noce_conversion_profitable_p call to determine whether the sequence is cost effective.

Also make sure arm_noce_conversion_profitable_p accepts vsel<cond> patterns for Armv8.1-M Mainline targets.

gcc/ChangeLog:

        * config/arm/arm.cc (arm_noce_conversion_profitable_p): Call
        default_noce_conversion_profitable_p when not dealing with the
        armv8.1-m.main special case.
        (arm_is_vsel_fp_insn): New function.


Regression tested on arm-none-eabi with -mcpu=cortex-m3 and -mcpu=cortex-m55/-mfloat-abi=hard.

OK for trunk?

diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 
5c11621327e15b7212b2290769cc0a922347ce2d..41f70154381bcfee3489841c05e4233310f2acee
 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -36092,6 +36092,51 @@ arm_get_mask_mode (machine_mode mode)
   return default_get_mask_mode (mode);
 }
 
+/* Helper function to determine whether SEQ represents a sequence of
+   instructions representing the vsel<cond> floating point instructions.  */
+
+static bool
+arm_is_vsel_fp_insn (rtx_insn *seq)
+{
+  rtx_insn *curr_insn = seq;
+  rtx set = NULL_RTX;
+  /* The pattern may start with a simple set with register operands.  Skip
+     through any of those.  */
+  while (curr_insn)
+    {
+      set = single_set (curr_insn);
+      if (!set
+         || !REG_P (SET_DEST (set)))
+       return false;
+
+      if (!REG_P (SET_SRC (set)))
+       break;
+      curr_insn = NEXT_INSN (curr_insn);
+    }
+
+  if (!set)
+    return false;
+
+  /* The next instruction should be a compare.  */
+  if (!REG_P (SET_DEST (set))
+      || GET_CODE (SET_SRC (set)) != COMPARE)
+    return false;
+
+  curr_insn = NEXT_INSN (curr_insn);
+  if (!curr_insn)
+    return false;
+
+  /* And the last instruction should be an IF_THEN_ELSE.  */
+  set = single_set (curr_insn);
+  if (!set
+      || !REG_P (SET_DEST (set))
+      || GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
+    return false;
+
+  return !NEXT_INSN (curr_insn);
+}
+
+
 /* Helper function to determine whether SEQ represents a sequence of
    instructions representing the Armv8.1-M Mainline conditional arithmetic
    instructions: csinc, csneg and csinv. The cinc instruction is generated
@@ -36164,15 +36209,20 @@ arm_is_v81m_cond_insn (rtx_insn *seq)
    hook to only allow "noce" to generate the patterns that are profitable.  */
 
 bool
-arm_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *)
+arm_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
 {
   if (!TARGET_COND_ARITH
       || reload_completed)
-    return true;
+    return default_noce_conversion_profitable_p (seq, if_info);
 
   if (arm_is_v81m_cond_insn (seq))
     return true;
 
+  /* Look for vsel<cond> opportunities as we still want to codegen these for
+     Armv8.1-M Mainline targets.  */
+  if (arm_is_vsel_fp_insn (seq))
+    return true;
+
   return false;
 }
 

Reply via email to