aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Simoes Dias Vieira <andre.simoesdiasvieira@arm.com>2024-11-08 13:34:57 +0000
committerAndre Vieira <andre.simoesdiasvieira@arm.com>2024-11-08 13:35:57 +0000
commit1e8396464cb990d554c932cd959742b86660a25a (patch)
treed91ee878de5b8b2fff6323fab50fb564e2702542
parent5ff9e21c1ec81f8288e74679547e56051e051975 (diff)
downloadgcc-1e8396464cb990d554c932cd959742b86660a25a.zip
gcc-1e8396464cb990d554c932cd959742b86660a25a.tar.gz
gcc-1e8396464cb990d554c932cd959742b86660a25a.tar.bz2
arm: Improvements to arm_noce_conversion_profitable_p call [PR 116444]
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.
-rw-r--r--gcc/config/arm/arm.cc59
1 files changed, 56 insertions, 3 deletions
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 6f11b6c..0f72f3a 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -36100,9 +36100,57 @@ arm_get_mask_mode (machine_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;
}