Sorry for the slow reply, had a few days off. Xi Ruoyao <xry...@xry111.site> writes: > If we see a promoted subreg and TRULY_NOOP_TRUNCATION says the > truncation is not a noop, then all bits of the inner reg are live. We > cannot reduce the live mask to that of the mode of the subreg. > > gcc/ChangeLog: > > PR rtl-optimization/120050 > * ext-dce.cc (ext_dce_process_uses): Break early if a SUBREG in > rhs is promoted and the truncation from the inner mode to the > outer mode is not a noop when handling SETs. > --- > > Bootstrapped on mips64el-linux-gnuabi64. Ok for trunk? > > gcc/ext-dce.cc | 12 ++++++++++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > > diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc > index a0343950141..3b21e68b90c 100644 > --- a/gcc/ext-dce.cc > +++ b/gcc/ext-dce.cc > @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see > #include "print-rtl.h" > #include "dbgcnt.h" > #include "diagnostic-core.h" > +#include "target.h" > > /* These should probably move into a C++ class. */ > static vec<bitmap_head> livein; > @@ -764,13 +765,20 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, > We don't want to mark those bits live unnecessarily > as that inhibits extension elimination in important > cases such as those in Coremark. So we need that > - outer code. */ > + outer code. > + > + But if !TRULY_NOOP_TRUNCATION_MODES_P, those bits > + may be actually alive with any promoted subreg > + regardless of the outer code. See PR 120050. */
How about expanding on this a bit: If !TRULY_NOOP_TRUNCATION_MODES_P holds true for the subreg, then the mode change performed by Y would normally need to be a TRUNCATE rather than a SUBREG. It is probably the guarantee provided by SUBREG_PROMOTED_VAR_P that allows the SUBREG in Y as an exception. We must therefore preserve that guarantee and treat the upper bits of the inner register as live regardless of the outer code. See PR 120050. */ OK with that change, thanks. Richard > if (!REG_P (SUBREG_REG (y)) > || (SUBREG_PROMOTED_VAR_P (y) > && ((GET_CODE (SET_SRC (x)) == SIGN_EXTEND > && SUBREG_PROMOTED_SIGNED_P (y)) > || (GET_CODE (SET_SRC (x)) == ZERO_EXTEND > - && SUBREG_PROMOTED_UNSIGNED_P (y))))) > + && SUBREG_PROMOTED_UNSIGNED_P (y)) > + || !TRULY_NOOP_TRUNCATION_MODES_P ( > + GET_MODE (y), > + GET_MODE (SUBREG_REG (y)))))) > break; > > bit = subreg_lsb (y).to_constant ();