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

--- Comment #13 from Vladimir Makarov <vmakarov at gcc dot gnu.org> ---
(In reply to UroŇ° Bizjak from comment #11)
> (In reply to Jakub Jelinek from comment #5)
> > I guess it depends on what exactly a normal subreg on lhs means.
> > The documentation says:
> >           When used as an lvalue, 'subreg' is a word-based accessor.
> >           Storing to a 'subreg' modifies all the words of REG that
> >           overlap the 'subreg', but it leaves the other words of REG
> >           alone.
> 
> 
> But this wording applies only to multi-word registers. We can't use the
> above wording for 512bit single-word register, since we don't know how the
> move will affect the bits outside the subreg. We can say that the move
> "modifies all the words of REG that overlap the 'subreg', since we have only
> one 512-bit word of a 512-bit register.
> 

OK.

> So, I think that the transformation in the Comment 10 is invalid for
> registers that can't be decomposed to independent word-sized registers (to
> use "word-based accessor"), e.g. V32HImode xmm20. Perhaps the mentioned
> alter_subreg should choose correct approach based on TARGET_HARD_REGNO_NREGS?

Actually I do the same things as the old reload does.  It has practically the
same alter_subreg code.  May be the reload and LRA code is not up to date to
treat correctly this situation. I don't know.

  What I can do is to generate (strict_low_part (subreg:DI (reg:V32HI <sse
pseudo>))) to reflect the new semantics.  Something like

Index: lra.c
===================================================================
--- lra.c       (revision 258691)
+++ lra.c       (working copy)
@@ -487,14 +487,26 @@ int lra_curr_reload_num;
 void
 lra_emit_move (rtx x, rtx y)
 {
-  int old;
-
+  int old, regno;
+  machine_mode mode;
+  rtx reg;
+
   if (GET_CODE (y) != PLUS)
     {
       if (rtx_equal_p (x, y))
        return;
       old = max_reg_num ();
-      emit_move_insn (x, y);
+      if (GET_CODE (x) == SUBREG
+         && REG_P (reg = SUBREG_REG (x))
+         && GET_MODE_SIZE (mode = GET_MODE (reg)).to_constant () >
UNITS_PER_WORD
+         && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER
+         && ira_reg_class_max_nregs[lra_get_allocno_class (regno)][mode] == 1)
+       {
+         x = gen_rtx_STRICT_LOW_PART (VOIDmode, x);
+         emit_insn (gen_rtx_SET (x, y));
+       }
+      else
+       emit_move_insn (x, y);
       if (REG_P (x))
        lra_reg_info[ORIGINAL_REGNO (x)].last_reload = ++lra_curr_reload_num;
       /* Function emit_move can create pseudos -- so expand the pseudo


  But we need insn patterns for such cases which are absent in i386 md files. 
Without adding them, compiler will crash in LRA.

Reply via email to