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