On Thu, Aug 26, 2021 at 12:50 PM Richard Sandiford
<richard.sandif...@arm.com> wrote:
>
> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> > On Thu, Aug 26, 2021 at 11:06 AM Richard Sandiford
> > <richard.sandif...@arm.com> wrote:
> >>
> >> Richard Biener via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> >> > One thought I had is whether we can "fix" validate_subreg to have less
> >> > "weird" allowed float-int
> >> > special cases.  As said upthread I think that we either should allow
> >> > all of those, implying that
> >> > subregs work semantically as if there's subregs to same-sized integer
> >> > modes inbetween or
> >> > disallow them all and make sure we're actually doing that explicitely.
> >> >
> >> > For example
> >> >
> >> >   /* ??? Similarly, e.g. with (subreg:DF (reg:TI)).  Though 
> >> > store_bit_field
> >> >      is the culprit here, and not the backends.  */
> >> >   else if (known_ge (osize, regsize) && known_ge (isize, osize))
> >> >     ;
> >> >
> >> > I can't decipther rtl.text as to what the semantics of such a subreg is
> >> > given the docs hand-wave about WORDS_BIG_ENDIAN vs.
> >> > FLOAT_WORDS_BIG_ENDIAN but don't actually say what happens
> >> > when you mix those in a subreg.  So maybe the above should
> >> > have explicitely have WORDS_BIG_ENDIAN == FLOAT_WORDS_BIG_ENDIAN.
> >> >
> >> > But then the world would be much simpler if subregs of non-same size
> >> > modes have explicit documentation for the mode kinds we have.
> >>
> >> Yeah.  Although validate_subreg was a good idea, some of the mode checks
> >> are IMO a failed experiment.  The hope was that eventually we'd remove
> >> all those special exceptions once the culprit has been fixed.  However,
> >> the code is over 16 years old at this point and those changes never
> >> happened.
> >>
> >> Nested subregs aren't a thing (thankfully) and one of the big disadvantages
> >> of the current validate_subreg mode-changing rules is that they aren't
> >> transitive.  This can artificially require temporary pseudos for things
> >> that could be expressed directly as a single subreg.
> >
> > And that's what the proposed patch does (add same-mode size integer mode
> > punning intermediate subregs).
> >
> > So if that's not supposed to be necessary then why restrict subregs at all?
>
> I was trying to say: I'm not sure we should.
>
> > I mean you seem to imply that the semantics would be clear and well-defined
> > (to you - not to me).  The only thing is that of course not all subregs are
> > "implemented" by a target (or can be, w/o spilling).
>
> Yeah.  That's for TARGET_CAN_CHANGE_MODE_CLASS to decide.
> But it only comes in to play during RA or when trying to take
> the subreg of a particular hard register.  Transitivity doesn't
> matter so much for the hard register case since the result of
> simplify_gen_subreg should then be another hard register.
>
> > Which means - we should adjust validate_subreg with another special-case
> > or rather generalize the existing ones to an overall set that makes more
> > sense?
>
> Maybe it's too radical, but I would whether we should just get rid of:
>
>   /* ??? This should not be here.  Temporarily continue to allow word_mode
>      subregs of anything.  The most common offender is (subreg:SI (reg:DF)).
>      Generally, backends are doing something sketchy but it'll take time to
>      fix them all.  */
>   if (omode == word_mode)
>     ;
>   /* ??? Similarly, e.g. with (subreg:DF (reg:TI)).  Though store_bit_field
>      is the culprit here, and not the backends.  */
>   else if (known_ge (osize, regsize) && known_ge (isize, osize))
>     ;
>   /* Allow component subregs of complex and vector.  Though given the below
>      extraction rules, it's not always clear what that means.  */
>   else if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
>            && GET_MODE_INNER (imode) == omode)
>     ;
>   /* ??? x86 sse code makes heavy use of *paradoxical* vector subregs,
>      i.e. (subreg:V4SF (reg:SF) 0) or (subreg:V4SF (reg:V2SF) 0).  This
>      surely isn't the cleanest way to represent this.  It's questionable
>      if this ought to be represented at all -- why can't this all be hidden
>      in post-reload splitters that make arbitrarily mode changes to the
>      registers themselves.  */
>   else if (VECTOR_MODE_P (omode)
>            && GET_MODE_INNER (omode) == GET_MODE_INNER (imode))
>     ;
>   /* Subregs involving floating point modes are not allowed to
>      change size.  Therefore (subreg:DI (reg:DF) 0) is fine, but
>      (subreg:SI (reg:DF) 0) isn't.  */
>   else if (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
>     {
>       if (! (known_eq (isize, osize)
>              /* LRA can use subreg to store a floating point value in
>                 an integer mode.  Although the floating point and the
>                 integer modes need the same number of hard registers,
>                 the size of floating point mode can be less than the
>                 integer mode.  LRA also uses subregs for a register
>                 should be used in different mode in on insn.  */
>              || lra_in_progress))
>         return false;
>     }
>
> altogether.

Yeah, I would fully support this.  Maybe replace it with a comment
but I don't know what it should say.

Richard.

>
> Thanks,
> Richard

Reply via email to