diff options
author | Andre Simoes Dias Vieira <andre.simoesdiasvieira@arm.com> | 2024-11-08 13:34:57 +0000 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2024-11-08 13:35:57 +0000 |
commit | 1e8396464cb990d554c932cd959742b86660a25a (patch) | |
tree | d91ee878de5b8b2fff6323fab50fb564e2702542 /gcc | |
parent | 5ff9e21c1ec81f8288e74679547e56051e051975 (diff) | |
download | gcc-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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/arm/arm.cc | 59 |
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; } |