https://gcc.gnu.org/g:bba1c1817b17787f9cecca986de88cc728b03257

commit bba1c1817b17787f9cecca986de88cc728b03257
Author: Andre Vieira <andre.simoesdiasvie...@arm.com>
Date:   Fri Oct 4 13:43:46 2024 +0100

    arm: Fix missed CE optimization for armv8.1-m.main [PR 116444]
    
    This patch restores missed optimizations for armv8.1-m.main targets that 
were
    missed when the generation of csinc, csinv and csneg were enabled for the 
same
    with patch series containing:
    
    commit c2bb84be4a6e581bbf45891457ee632a07416982
    Author: Sudi Das <sudi....@arm.com>
    Date:   Fri Sep 18 15:47:46 2020 +0100
    
        [PATCH 2/5][Arm] New pattern for CSINV instructions
    
    The original patch series makes use of the "noce" machinery to transform RTL
    into patterns that later match the Armv8.1-M Mainline, by getting the target
    hook TARGET_HAVE_CONDITIONAL_EXECUTION, to return FALSE for such targets 
prior
    to reload_completed.  The same machinery however was transforming other RTL
    patterns which were later on causing the "ce" pass post reload_completed to 
no
    longer optimize conditional execution opportunities, which was causing the
    regression observed in PR target/116444, a regression of 
'testsuite/gcc.target/arm/thumb-ifcvt-2.c'
    when ran for an Armv8.1-M Mainline target.
    
    This patch implements the target hook TARGET_NOCE_CONVERSION_PROFITABLE_P to
    only allow "noce" to generate patterns that match CSINV, CSINC and CSNEG.  
Thus
    ensuring that the early "ce" passes do not ruin things for later ones.
    
    gcc/ChangeLog:
    
            PR target/116444
            * config/arm/arm-protos.h (arm_noce_conversion_profitable_p): New
            declaration.
            * config/arm/arm.cc (arm_is_v81m_cond_insn): New helper function 
used
            in ...
            (arm_noce_conversion_profitable_p): ... here. New function to 
implement
            ...
            (TARGET_NOCE_PROFITABLE_P): ... this target hook.  New define.
    
    (cherry picked from commit 7766a2c1eb683eeee352ce117e8ed014665f392f)

Diff:
---
 gcc/config/arm/arm-protos.h |  1 +
 gcc/config/arm/arm.cc       | 87 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 34d6be76e94a..525370a0c346 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -210,6 +210,7 @@ extern bool arm_pad_reg_upward (machine_mode, tree, int);
 #endif
 extern int arm_apply_result_size (void);
 extern opt_machine_mode arm_get_mask_mode (machine_mode mode);
+extern bool arm_noce_conversion_profitable_p (rtx_insn *,struct noce_if_info 
*);
 
 #endif /* RTX_CODE */
 
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index be75cd05037f..9eaac9e70187 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -835,6 +835,9 @@ static const scoped_attribute_specs *const 
arm_attribute_table[] =
 #undef TARGET_MODES_TIEABLE_P
 #define TARGET_MODES_TIEABLE_P arm_modes_tieable_p
 
+#undef TARGET_NOCE_CONVERSION_PROFITABLE_P
+#define TARGET_NOCE_CONVERSION_PROFITABLE_P arm_noce_conversion_profitable_p
+
 #undef TARGET_CAN_CHANGE_MODE_CLASS
 #define TARGET_CAN_CHANGE_MODE_CLASS arm_can_change_mode_class
 
@@ -36148,6 +36151,90 @@ 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 Armv8.1-M Mainline conditional arithmetic
+   instructions: csinc, csneg and csinv. The cinc instruction is generated
+   using a different mechanism.  */
+
+static bool
+arm_is_v81m_cond_insn (rtx_insn *seq)
+{
+  rtx_insn *curr_insn = seq;
+  rtx set;
+  /* 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 one of:
+     NEG: for csneg,
+     PLUS: for csinc,
+     NOT: for csinv.  */
+  if (GET_CODE (SET_SRC (set)) != NEG
+      && GET_CODE (SET_SRC (set)) != PLUS
+      && GET_CODE (SET_SRC (set)) != NOT)
+    return false;
+
+  curr_insn = NEXT_INSN (curr_insn);
+  if (!curr_insn)
+    return false;
+
+  /* The next instruction should be a COMPARE.  */
+  set = single_set (curr_insn);
+  if (!set
+      || !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);
+}
+
+/* For Armv8.1-M Mainline we have both conditional execution through IT blocks,
+   as well as conditional arithmetic instructions controlled by
+   TARGET_COND_ARITH.  To generate the latter we rely on a special part of the
+   "ce" pass that generates code for targets that don't support conditional
+   execution of general instructions known as "noce".  These transformations
+   happen before 'reload_completed'.  However, "noce" also triggers for some
+   unwanted patterns [PR 116444] that prevent "ce" optimisations after reload.
+   To make sure we can get both we use the TARGET_NOCE_CONVERSION_PROFITABLE_P
+   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 *if_info)
+{
+  if (!TARGET_COND_ARITH
+      || reload_completed)
+    return true;
+
+  if (arm_is_v81m_cond_insn (seq))
+    return true;
+
+  return false;
+}
+
 /* Output assembly to read the thread pointer from the appropriate TPIDR
    register into DEST.  If PRED_P also emit the %? that can be used to
    output the predication code.  */

Reply via email to