https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94541

--- Comment #12 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Andrew Pinski from comment #11)
> (In reply to H.J. Lu from comment #10)
> > (In reply to Andrew Pinski from comment #8)
> > > (In reply to H.J. Lu from comment #7)
> > > > After 284r.ira:
> > > 
> > > That is fine according to the rules as long as 
> > > TARGET_TRULY_NOOP_TRUNCATION 
> > > is true.
> > 
> > We can't turn
> > 
> > (insn 13 12 14 3 (set (reg:SI 4 si)
> >         (subreg:SI (reg/v:DI 85 [ b ]) 0)) "y.i":14:14 67 {*movsi_internal}
> >      (expr_list:REG_DEAD (reg/v:DI 85 [ b ])
> >         (nil)))
> > 
> > into
> > 
> > 
> > (insn 13 12 14 3 (set (reg:SI 4 si)
> >         (reg:SI 4 si [orig:85 b ] [85])) "y.i":14:14 67 {*movsi_internal}
> >      (expr_list:REG_DEAD (reg/v:DI 4 si [orig:85 b ] [85])
> >         (nil)))
> > 
> > This is simple wrong.
> 
> How is that wrong?  What register was 85 assigned to?  4?
> Then is fully correct as TARGET_TRULY_NOOP_TRUNCATION is true for those
> sizes.  
> 
> On MIPS,  TARGET_TRULY_NOOP_TRUNCATION is false for SI/DI truncation.
> You need TARGET_TRULY_NOOP_TRUNCATION to be false for those sizes and you
> get a truncate RTL instead of the subreg.  subreg means the upper bits of
> the register are undefined.

In this case, upper bits in 85 are undefined:

(insn 13 12 14 3 (set (reg:SI 4 si)
        (subreg:SI (reg/v:DI 4 si [orig:85 b ] [85]) 0)) "y.i":14:14 67
{*movsi_internal}
     (expr_list:REG_DEAD (reg/v:DI 4 si [orig:85 b ] [85])
        (nil)))

LRA has:

         for (i = id->insn_static_data->n_operands - 1; i >= 0; i--)
            if ((DEBUG_INSN_P (insn) || ! static_id->operand[i].is_operator)
                && alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
              {
                lra_update_dup (id, i);
                insn_change_p = true;
              }
          if (insn_change_p)
            lra_update_operator_dups (id);

          if ((set = single_set (insn)) != NULL
              && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
              && REGNO (SET_SRC (set)) == REGNO (SET_DEST (set)))
            {
              /* Remove an useless move insn.  IRA can generate move
                 insns involving pseudos.  It is better remove them
                 earlier to speed up compiler a bit.  It is also
                 better to do it here as they might not pass final RTL
                 check in LRA, (e.g. insn moving a control register
                 into itself).  */
              lra_invalidate_insn_data (insn);
              delete_insn (insn);
            }

But

(insn 13 12 14 3 (set (reg:SI 4 si)
        (subreg:SI (reg/v:DI 4 si [orig:85 b ] [85]) 0)) "y.i":14:14 67
{*movsi_internal}
     (expr_list:REG_DEAD (reg/v:DI 4 si [orig:85 b ] [85])
        (nil)))

isn't useless and shouldn't be removed.

Reply via email to