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 ();

Reply via email to