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