On 2025/09/23 2:42, Max Filippov wrote:
Hi Suwa-san,
Hi Max,

This change introduces the following new regressions:
Ah, I was mistaken, split_DI_DF_const() is something that must be called if 
necessary, not an optimization option.

Also, applying this new patch will cause the subsequent "constantsynth v2" 
patch to fail, so please change:

        if (optimize_enabled)
          split_DI_DF_const (insn);

to:

        if (replacing_required)
          split_DI_DF_const (insn);

and then apply it.

--- 8< ---

This patch moves the process of splitting D[IF]mode constant assignments
into SImode ones from the define_split implementation after reloading to
processing within the "xt_largeconst" target-specific pass.

This allows these assignments to be processed by the "constantsynth"
optimization, which will be reimplemented later.

gcc/ChangeLog:

        * config/xtensa/xtensa-protos.h
        (xtensa_split_DI_reg_imm): Remove.
        * config/xtensa/xtensa.cc (xtensa_split_DI_reg_imm): Remove.
        (split_DI_DF_const): New worker function.
        (do_largeconst): Add a call to split_DI_DF_const() to the insn
        enumeration loop.
        * config/xtensa/xtensa.md (movdi): Remove split code when the
        source is constant.
        (movdi_internal): Add a new constraint pair (a, Y) to the second
        of the existing constraint alternatives.
        (The auxiliary define_split for movdi_internal): Remove.
---
 gcc/config/xtensa/xtensa-protos.h |  1 -
 gcc/config/xtensa/xtensa.cc       | 82 +++++++++++++++++++++++--------
 gcc/config/xtensa/xtensa.md       | 39 +++------------
 3 files changed, 67 insertions(+), 55 deletions(-)

diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index c538e483cfc..562e4b9283b 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -59,7 +59,6 @@ extern char *xtensa_emit_sibcall (int, rtx *);
 extern bool xtensa_tls_referenced_p (rtx);
 extern enum rtx_code xtensa_shlrd_which_direction (rtx, rtx);
 extern bool xtensa_postreload_completed_p (void);
-extern void xtensa_split_DI_reg_imm (rtx *);
 extern char *xtensa_bswapsi2_output (rtx_insn *, const char *);
#ifdef TREE_CODE
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index c878f1183c6..b6447dc2cdc 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -2633,27 +2633,6 @@ xtensa_postreload_completed_p (void)
 }
-/* Split a DImode pair of reg (operand[0]) and const_int (operand[1]) into
-   two SImode pairs, the low-part (operands[0] and [1]) and the high-part
-   (operands[2] and [3]).  */
-
-void
-xtensa_split_DI_reg_imm (rtx *operands)
-{
-  rtx lowpart, highpart;
-
-  if (WORDS_BIG_ENDIAN)
-    split_double (operands[1], &highpart, &lowpart);
-  else
-    split_double (operands[1], &lowpart, &highpart);
-
-  operands[3] = highpart;
-  operands[2] = gen_highpart (SImode, operands[0]);
-  operands[1] = lowpart;
-  operands[0] = gen_lowpart (SImode, operands[0]);
-}
-
-
 /* Return the asm output string of bswapsi2_internal insn pattern.
    It does this by scanning backwards for the BB from the specified insn,
    and if an another bswapsi2_internal is found, it omits the instruction
@@ -5892,6 +5871,61 @@ FPreg_neg_scaled_simm12b (rtx_insn *insn)
   return false;
 }
+/* Split D[IF]mode constant assignments into pairs of SImode ones. This
+   is also the pre-processing for constantsynth optimization that follows
+   immediately after.  */
+
+static bool
+split_DI_DF_const (rtx_insn *insn)
+{
+  rtx pat, dest, src, dest0, dest1, src0, src1, src0c, src1c;
+  int regno;
+
+  if (GET_CODE (pat = PATTERN (insn)) == SET
+      && REG_P (dest = SET_DEST (pat)) && GP_REG_P (regno = REGNO (dest))
+      && (src = avoid_constant_pool_reference (SET_SRC (pat)),
+         ((GET_MODE (dest) == DImode && CONST_INT_P (src))
+          || (GET_MODE (dest) == DFmode && CONST_DOUBLE_P (src)
+              && GET_MODE (src) == DFmode))))
+    {
+      /* Splitting a D[IF]mode literal constant into two with split_double()
+        results in a pair of CONST_INTs, so they are assigned in SImode
+        regardless of the original source mode.  */
+      dest0 = gen_rtx_REG (SImode, regno);
+      dest1 = gen_rtx_REG (SImode, regno + 1);
+      split_double (src, &src0, &src1);
+      if (dump_file)
+       {
+         fputs ("split_DI_DF_const: ", dump_file);
+         dump_value_slim (dump_file, src, 0);
+         fputs (" -> (", dump_file);
+         dump_value_slim (dump_file, src0, 0);
+         fputs (", ", dump_file);
+         dump_value_slim (dump_file, src1, 0);
+         fputs (")\n", dump_file);
+       }
+      src1c = src0c = NULL_RTX;
+      if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS)
+       {
+         if (! xtensa_simm12b (INTVAL (src0)))
+           src0c = src0, src0 = force_const_mem (SImode, src0);
+         if (! xtensa_simm12b (INTVAL (src1)))
+           src1c = src1, src1 = force_const_mem (SImode, src1);
+       }
+      remove_reg_equal_equiv_notes (insn);
+      validate_change (insn, &PATTERN (insn),
+                      gen_rtx_SET (dest0, src0), 0);
+      if (src0c)
+       add_reg_note (insn, REG_EQUIV, copy_rtx (src0c));
+      insn = emit_insn_after (gen_rtx_SET (dest1, src1), insn);
+      if (src1c)
+       add_reg_note (insn, REG_EQUIV, copy_rtx (src1c));
+      return true;
+    }
+
+  return false;
+}
+
 /* Replace the source of [SH]Imode allocation whose value does not fit
    into signed 12 bits with a reference to litpool entry.  */
@@ -5970,6 +6004,12 @@ do_largeconst (void)
           fit into signed 12 bits with a reference to litpool entry.  */
        if (replacing_required)
          litpool_set_src (insn);
+
+       /* Split D[IF]mode constant assignments into pairs of SImode ones.
+          This is also the pre-processing for constantsynth optimization
+          that follows immediately after.  */
+       if (replacing_required)
+         split_DI_DF_const (insn);
       }
 }
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 9a0c631dc3f..a5c8a66aafb 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1219,22 +1219,8 @@
        (match_operand:DI 1 "general_operand" ""))]
   ""
 {
-  if (CONSTANT_P (operands[1]))
-    {
-      /* Split in halves if 64-bit Const-to-Reg moves
-        because of offering further optimization opportunities.  */
-      if (register_operand (operands[0], DImode))
-       {
-         rtx ops[4] = { operands[0], operands[1] };
-         xtensa_split_DI_reg_imm (ops);
-         emit_move_insn (ops[0], ops[1]);
-         emit_move_insn (ops[2], ops[3]);
-         DONE;
-       }
-
-      if (!TARGET_CONST16)
-       operands[1] = force_const_mem (DImode, operands[1]);
-    }
+  if (!TARGET_CONST16 && CONSTANT_P (operands[1]))
+    operands[1] = force_const_mem (DImode, operands[1]);
if (!register_operand (operands[0], DImode)
       && !register_operand (operands[1], DImode))
@@ -1244,8 +1230,8 @@
 })
(define_insn_and_split "movdi_internal"
-  [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U")
-       (match_operand:DI 1 "move_operand" "r,i,T,U,r"))]
+  [(set (match_operand:DI 0 "nonimmed_operand" "=a,a,W,a,a,U")
+       (match_operand:DI 1 "move_operand" "r,Y,i,T,U,r"))]
   "register_operand (operands[0], DImode)
    || register_operand (operands[1], DImode)"
   "#"
@@ -1260,22 +1246,9 @@
       std::swap (operands[2], operands[3]);
     }
 }
-  [(set_attr "type"  "move,move,load,load,store")
+  [(set_attr "type"  "move,load,move,load,load,store")
    (set_attr "mode"  "DI")
-   (set_attr "length"        "6,12,6,6,6")])
-
-(define_split
-  [(set (match_operand:DI 0 "register_operand")
-       (match_operand:DI 1 "const_int_operand"))]
-  "!TARGET_CONST16
-   && ! xtensa_postreload_completed_p ()"
-  [(set (match_dup 0)
-       (match_dup 1))
-   (set (match_dup 2)
-       (match_dup 3))]
-{
-  xtensa_split_DI_reg_imm (operands);
-})
+   (set_attr "length"        "6,6,12,6,6,6")])
;; 32-bit Integer moves --
2.39.5

Reply via email to