]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm: Improvements to arm_noce_conversion_profitable_p call [PR 116444]
authorAndre Simoes Dias Vieira <andre.simoesdiasvieira@arm.com>
Fri, 8 Nov 2024 13:34:57 +0000 (13:34 +0000)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Fri, 8 Nov 2024 13:35:57 +0000 (13:35 +0000)
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:

PR target/116444
* 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.

gcc/config/arm/arm.cc

index 6f11b6c816d4c01a798e85202f2f256260ff416b..0f72f3a9031237192c6362760203fe489946b948 100644 (file)
@@ -36099,10 +36099,58 @@ 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.
+   This is an heuristic to check whether the proposed optimisation is desired,
+   the choice has no consequence for correctness.  */
+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
-   using a different mechanism.  */
+   using a different mechanism.
+   This is an heuristic to check whether the proposed optimisation is desired,
+   the choice has no consequence for correctness.  */
 
 static bool
 arm_is_v81m_cond_insn (rtx_insn *seq)
@@ -36171,15 +36219,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;
 }