On Tue, Aug 25, 2026 at 7:27 AM feedable via Sourceware Forge
<[email protected]> wrote:
>
> From: feedable <[email protected]>
>
> ix86_split_long_move is using parts of the the operands array that are not
> set by the recog machionery as storage space, which makes the logic confusing
> and also interferes with making the operand count dynamic.
>
> Use local arrays instead.
One question, does the match_dup in the split output template but not
in input pattern also be considered improper storage of operands
array?

.i.e for below pattern in i386.md, input pattern only has 2 operands,
but the output template has match_dup 4 and match_dup 5.
Does genconfig count operand numbers for split's output template? Does
dynamic operand count handle that?

(define_insn_and_split "*cmp<dwi>_doubleword"
 [(set (reg:CCZ FLAGS_REG)
       (compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
                    (match_operand:<DWI> 1 "general_operand")))]
 "ix86_pre_reload_split ()"
 "#"
 "&& 1"
 [(parallel [(set (reg:CCZ FLAGS_REG)
                  (compare:CCZ (ior:DWIH (match_dup 4) (match_dup 5))
                               (const_int 0)))
             (set (match_dup 4) (ior:DWIH (match_dup 4) (match_dup 5)))])]

 split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);

 operands[4] = gen_reg_rtx (<MODE>mode);

 /* Special case comparisons against -1.  */
 if (operands[1] == constm1_rtx && operands[3] == constm1_rtx)
   {
     emit_insn (gen_and<mode>3 (operands[4], operands[0], operands[2]));
     emit_insn (gen_cmp_1 (<MODE>mode, operands[4], constm1_rtx));
     DONE;
   }

>
> gcc/ChangeLog:
>
>         * config/i386/i386-expand.cc (ix86_split_to_parts): Use automatic
>         storage for temporaries.
>         (ix86_split_long_move): Likewise.
>         * config/i386/i386.md: Likewise.
> ---
>  gcc/config/i386/i386-expand.cc |  26 ++++----
>  gcc/config/i386/i386.md        | 113 ++++++++++++++++-----------------
>  2 files changed, 69 insertions(+), 70 deletions(-)
>
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index 34c9599f928e6..8f42297263d3c 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -6420,8 +6420,7 @@ ix86_split_to_parts (rtx operand, rtx *parts, 
> machine_mode mode)
>
>  /* Emit insns to perform a move or push of DI, DF, XF, and TF values.
>     Return false when normal moves are needed; true when all required
> -   insns have been emitted.  Operands 2-4 contain the input values
> -   int the correct order; operands 5-7 contain the output values.  */
> +   insns have been emitted.  */
>
>  void
>  ix86_split_long_move (rtx operands[])
> @@ -6602,6 +6601,7 @@ ix86_split_long_move (rtx operands[])
>        return;
>      }
>
> +  rtx move_src[4], move_dst[4];
>    /* Choose correct order to not overwrite the source before it is copied.  
> */
>    if ((REG_P (part[0][0])
>         && REG_P (part[1][1])
> @@ -6615,31 +6615,31 @@ ix86_split_long_move (rtx operands[])
>      {
>        for (i = 0, j = nparts - 1; i < nparts; i++, j--)
>         {
> -         operands[2 + i] = part[0][j];
> -         operands[6 + i] = part[1][j];
> +         move_src[i] = part[0][j];
> +         move_dst[i] = part[1][j];
>         }
>      }
>    else
>      {
>        for (i = 0; i < nparts; i++)
>         {
> -         operands[2 + i] = part[0][i];
> -         operands[6 + i] = part[1][i];
> +         move_src[i] = part[0][i];
> +         move_dst[i] = part[1][i];
>         }
>      }
>
>    /* Attempt to locally unCSE nonzero constants.  */
>    for (j = 0; j < nparts - 1; j++)
> -    if (CONST_INT_P (operands[6 + j])
> -       && operands[6 + j] != const0_rtx
> -       && REG_P (operands[2 + j]))
> +    if (CONST_INT_P (move_dst[j])
> +       && move_dst[j] != const0_rtx
> +       && REG_P (move_src[j]))
>        for (i = j; i < nparts - 1; i++)
> -       if (CONST_INT_P (operands[7 + i])
> -           && INTVAL (operands[7 + i]) == INTVAL (operands[6 + j]))
> -         operands[7 + i] = operands[2 + j];
> +       if (CONST_INT_P (move_dst[1 + i])
> +           && INTVAL (move_dst[1 + i]) == INTVAL (move_dst[j]))
> +         move_dst[1 + i] = move_src[j];
>
>    for (i = 0; i < nparts; i++)
> -    emit_move_insn (operands[2 + i], operands[6 + i]);
> +    emit_move_insn (move_src[i], move_dst[i]);
>
>    return;
>  }
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 4e18797743f48..63f744daab63e 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -3779,8 +3779,8 @@
>    "&& reload_completed"
>    [(const_int 0)]
>  {
> -  operands[4] = gen_lowpart (DImode, operands[1]);
> -  split_double_concat (TImode, operands[0], operands[4], operands[2]);
> +  rtx temp = gen_lowpart (DImode, operands[1]);
> +  split_double_concat (TImode, operands[0], temp, operands[2]);
>    DONE;
>  })
>
> @@ -3801,8 +3801,8 @@
>    "&& reload_completed"
>    [(const_int 0)]
>  {
> -  operands[4] = gen_highpart (DImode, operands[1]);
> -  split_double_concat (TImode, operands[0], operands[2], operands[4]);
> +  rtx temp = gen_highpart (DImode, operands[1]);
> +  split_double_concat (TImode, operands[0], operands[2], temp);
>    DONE;
>  })
>
> @@ -3821,8 +3821,8 @@
>    "&& reload_completed"
>    [(const_int 0)]
>  {
> -  operands[4] = gen_highpart (SImode, operands[1]);
> -  split_double_concat (DImode, operands[0], operands[2], operands[4]);
> +  rtx temp = gen_highpart (SImode, operands[1]);
> +  split_double_concat (DImode, operands[0], operands[2], temp);
>    DONE;
>  })
>
> @@ -5117,10 +5117,11 @@
>    [(const_int 0)]
>  {
>    rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
> +  rtx lowpart, highpart;
>
> -  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
> +  split_double_mode (<DWI>mode, &operands[0], 1, &lowpart, &highpart);
>
> -  emit_move_insn (operands[3], operands[1]);
> +  emit_move_insn (lowpart, operands[1]);
>
>    /* Generate a cltd if possible and doing so it profitable.  */
>    if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
> @@ -5134,7 +5135,7 @@
>        emit_move_insn (operands[2], operands[1]);
>        emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
>      }
> -  emit_move_insn (operands[4], operands[2]);
> +  emit_move_insn (highpart, operands[2]);
>    DONE;
>  })
>
> @@ -5191,29 +5192,30 @@
>    [(const_int 0)]
>  {
>    rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
> +  rtx lowpart, highpart;
>
> -  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
> +  split_double_mode (<DWI>mode, &operands[0], 1, &lowpart, &highpart);
>
> -  if (REGNO (operands[3]) != REGNO (operands[1]))
> -    emit_move_insn (operands[3], operands[1]);
> +  if (REGNO (lowpart) != REGNO (operands[1]))
> +    emit_move_insn (lowpart, operands[1]);
>
>    rtx src = operands[1];
> -  if (REGNO (operands[3]) == AX_REG)
> -    src = operands[3];
> +  if (REGNO (lowpart) == AX_REG)
> +    src = lowpart;
>
>    /* Generate a cltd if possible and doing so it profitable.  */
>    if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
>        && REGNO (src) == AX_REG
> -      && REGNO (operands[4]) == DX_REG)
> +      && REGNO (highpart) == DX_REG)
>      {
> -      emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
> +      emit_insn (gen_ashr<mode>3_cvt (highpart, src, bits));
>        DONE;
>      }
>
> -  if (REGNO (operands[4]) != REGNO (operands[1]))
> -    emit_move_insn (operands[4], operands[1]);
> +  if (REGNO (highpart) != REGNO (operands[1]))
> +    emit_move_insn (highpart, operands[1]);
>
> -  emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
> +  emit_insn (gen_ashr<mode>3_cvt (highpart, highpart, bits));
>    DONE;
>  })
>
> @@ -6317,16 +6319,16 @@
>         || TARGET_AVX512VL)"
>    [(const_int 0)]
>  {
> -  operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
> -  operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
> +  rtx lowpart_sse = lowpart_subreg (<ssevecmode>mode, operands[0], 
> <MODE>mode);
> +  rtx lowpart_v4si = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
>
> -  emit_insn (gen_sse2_loadld (operands[4],
> +  emit_insn (gen_sse2_loadld (lowpart_v4si,
>                               CONST0_RTX (V4SImode), operands[1]));
>
>    if (<ssevecmode>mode == V4SFmode)
> -    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
> +    emit_insn (gen_floatv4siv4sf2 (lowpart_sse, lowpart_v4si));
>    else
> -    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
> +    emit_insn (gen_sse2_cvtdq2pd (lowpart_sse, lowpart_v4si));
>    DONE;
>  })
>
> @@ -13330,32 +13332,32 @@
>    [(const_int:DWIH 0)]
>  {
>    bool emit_insn_deleted_note_p = false;
> +  rtx lowpart[3], highpart[3];
> +  split_double_mode (<DWI>mode, &operands[0], 3, lowpart, highpart);
>
> -  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
> -
> -  if (operands[2] == const0_rtx)
> -    emit_move_insn (operands[0], const0_rtx);
> -  else if (operands[2] == constm1_rtx)
> +  if (lowpart[2] == const0_rtx)
> +    emit_move_insn (lowpart[0], const0_rtx);
> +  else if (lowpart[2] == constm1_rtx)
>      {
> -      if (!rtx_equal_p (operands[0], operands[1]))
> -       emit_move_insn (operands[0], operands[1]);
> +      if (!rtx_equal_p (lowpart[0], lowpart[1]))
> +       emit_move_insn (lowpart[0], lowpart[1]);
>        else
>         emit_insn_deleted_note_p = true;
>      }
>    else
> -    ix86_expand_binary_operator (AND, <MODE>mode, &operands[0], 
> TARGET_APX_NDD);
> +    ix86_expand_binary_operator (AND, <MODE>mode, &lowpart[0], 
> TARGET_APX_NDD);
>
> -  if (operands[5] == const0_rtx)
> -    emit_move_insn (operands[3], const0_rtx);
> -  else if (operands[5] == constm1_rtx)
> +  if (highpart[2] == const0_rtx)
> +    emit_move_insn (highpart[0], const0_rtx);
> +  else if (highpart[2] == constm1_rtx)
>      {
> -      if (!rtx_equal_p (operands[3], operands[4]))
> -       emit_move_insn (operands[3], operands[4]);
> +      if (!rtx_equal_p (highpart[0], highpart[1]))
> +       emit_move_insn (highpart[0], highpart[1]);
>        else if (emit_insn_deleted_note_p)
>         emit_note (NOTE_INSN_DELETED);
>      }
>    else
> -    ix86_expand_binary_operator (AND, <MODE>mode, &operands[3], 
> TARGET_APX_NDD);
> +    ix86_expand_binary_operator (AND, <MODE>mode, &highpart[0], 
> TARGET_APX_NDD);
>
>    DONE;
>  }
> @@ -14388,45 +14390,42 @@
>       and operands[0] == operands[1], which requires a NOTE_INSN_DELETED.  */
>    bool emit_insn_deleted_note_p = false;
>
> -  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
> +  rtx lowpart[3], highpart[3];
> +  split_double_mode (<DWI>mode, &operands[0], 3, lowpart, highpart);
>
> -  if (operands[2] == const0_rtx)
> +  if (lowpart[2] == const0_rtx)
>      {
> -      if (!rtx_equal_p (operands[0], operands[1]))
> -       emit_move_insn (operands[0], operands[1]);
> +      if (!rtx_equal_p (lowpart[0], lowpart[1]))
> +       emit_move_insn (lowpart[0], lowpart[1]);
>        else
>         emit_insn_deleted_note_p = true;
>      }
> -  else if (operands[2] == constm1_rtx)
> +  else if (lowpart[2] == constm1_rtx)
>      {
>        if (<CODE> == IOR)
> -       emit_move_insn (operands[0], constm1_rtx);
> +       emit_move_insn (lowpart[0], constm1_rtx);
>        else
> -       ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0],
> -                                   TARGET_APX_NDD);
> +       ix86_expand_unary_operator (NOT, <MODE>mode, lowpart, TARGET_APX_NDD);
>      }
>    else
> -    ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0],
> -                                TARGET_APX_NDD);
> +    ix86_expand_binary_operator (<CODE>, <MODE>mode, lowpart, 
> TARGET_APX_NDD);
>
> -  if (operands[5] == const0_rtx)
> +  if (highpart[2] == const0_rtx)
>      {
> -      if (!rtx_equal_p (operands[3], operands[4]))
> -       emit_move_insn (operands[3], operands[4]);
> +      if (!rtx_equal_p (highpart[0], highpart[1]))
> +       emit_move_insn (highpart[0], highpart[1]);
>        else if (emit_insn_deleted_note_p)
>         emit_note (NOTE_INSN_DELETED);
>      }
> -  else if (operands[5] == constm1_rtx)
> +  else if (highpart[2] == constm1_rtx)
>      {
>        if (<CODE> == IOR)
> -       emit_move_insn (operands[3], constm1_rtx);
> +       emit_move_insn (highpart[0], constm1_rtx);
>        else
> -       ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3],
> -                                   TARGET_APX_NDD);
> +       ix86_expand_unary_operator (NOT, <MODE>mode, highpart, 
> TARGET_APX_NDD);
>      }
>    else
> -    ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3],
> -                                TARGET_APX_NDD);
> +    ix86_expand_binary_operator (<CODE>, <MODE>mode, highpart, 
> TARGET_APX_NDD);
>
>    DONE;
>  }
> --
> 2.54.0
>


--
BR,
Hongtao

Reply via email to