Sorry for the slow reply, had a few days off.
Xi Ruoyao <[email protected]> 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 ();