diff mbox series

arm: Improvements to arm_noce_conversion_profitable_p call [PR 116444]

Message ID 1a80bfb1-6c86-44f7-a149-28f924e967ff@arm.com
State New
Headers show
Series arm: Improvements to arm_noce_conversion_profitable_p call [PR 116444] | expand

Commit Message

Andre Vieira (lists) Oct. 18, 2024, 3:53 p.m. UTC
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 mbox series

Patch

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;
 }