YunQiang Su <yunqiang...@cipunited.com> writes:
> PR #104914
>
> On TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode)) == true platforms,
> zero_extract (SI, SI) can be sign-extended.  So, if a zero_extract (DI,
> DI) following with an sign_extend(SI, DI) can be merged to a single
> zero_extract (SI, SI).
>
> gcc/ChangeLog:
>       PR: 104914.
>       * combine.cc (try_combine): Combine zero_extract (DI, DI) and
>         following sign_extend (DI, SI) for
>         TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode)) == true.
>         (subst): Allow replacing reg(DI) with subreg(SI (reg DI))
>         if to is SImode and from is DImode for
>         TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode)) == true.
>
> gcc/testsuite/ChangeLog:
>       PR: 104914.
>       * gcc.target/mips/pr104914.c: New testcase.
> ---
>  gcc/combine.cc                           | 88 ++++++++++++++++++++----
>  gcc/testsuite/gcc.target/mips/pr104914.c | 17 +++++
>  2 files changed, 90 insertions(+), 15 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/mips/pr104914.c
>
> diff --git a/gcc/combine.cc b/gcc/combine.cc
> index e46d202d0a7..701b7c33b17 100644
> --- a/gcc/combine.cc
> +++ b/gcc/combine.cc
> @@ -3294,15 +3294,64 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn 
> *i1, rtx_insn *i0,
>        n_occurrences = 0;             /* `subst' counts here */
>        subst_low_luid = DF_INSN_LUID (i2);
>  
> -      /* If I1 feeds into I2 and I1DEST is in I1SRC, we need to make a unique
> -      copy of I2SRC each time we substitute it, in order to avoid creating
> -      self-referential RTL when we will be substituting I1SRC for I1DEST
> -      later.  Likewise if I0 feeds into I2, either directly or indirectly
> -      through I1, and I0DEST is in I0SRC.  */
> -      newpat = subst (PATTERN (i3), i2dest, i2src, false, false,
> -                   (i1_feeds_i2_n && i1dest_in_i1src)
> -                   || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n))
> -                       && i0dest_in_i0src));
> +      /* Try to combine zero_extract (DImode) and sign_extend (SImode to 
> DImode)
> +      for TARGET_TRULY_NOOP_TRUNCATION.  The RTL may look like:
> +
> +      (insn 10 49 11 2 (set (zero_extract:DI (reg/v:DI 200 [ val ])
> +             (const_int 8 [0x8])
> +             (const_int 0 [0]))
> +          (subreg:DI (reg:QI 202 [ *buf_8(D) ]) 0)) "xx.c":4:29 278 {*insvdi}
> +          (expr_list:REG_DEAD (reg:QI 202 [ *buf_8(D) ]) (nil)))
> +      (insn 11 10 12 2 (set (reg/v:DI 200 [ val ])
> +
> +      (sign_extend:DI (subreg:SI (reg/v:DI 200 [ val ]) 0))) 238 
> {extendsidi2}
> +          (nil))

Like I mentioned in the other thread, I think things went wrong when
we generated the subreg in this sign_extend.  The operation should
have been a truncate of (reg/v:DI 200) followed by a sign extension
of the result.

What piece of code is generating the subreg?

Thanks,
Richard

Reply via email to