Hi! On Thu, Sep 10, 2020 at 12:21:47PM +0200, Ilya Leoshkevich wrote: > On Wed, 2020-09-09 at 16:09 -0500, Segher Boessenkool wrote: > > On Wed, Sep 09, 2020 at 11:50:56AM +0200, Ilya Leoshkevich via Gcc > > wrote: > > > I have a vector pseudo containing a single 128-bit value (V1TFmode) > > > and > > > I need to access its last 64 bits (DFmode). Which of the two > > > options > > > is better? > > > > > > (subreg:DF (reg:V1TF) 8) > > > > > > or > > > > > > (vec_select:DF (subreg:V2DF (reg:V1TF) 0) (parallel [(const_int > > > 1)])) > > > > > > If I use the first one, I run into a problem with set_noop_p (): it > > > thinks that > > > > > > (set (subreg:DF (reg:TF %f0) 8) (subreg:DF (reg:V1TF %f0) 8)) > > > > > > is a no-op, because it doesn't check the mode after stripping the > > > subreg: > > > > > > https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/rtlanal.c;h=5ae38b79#l1616 > > > > > > However this is not correct, because SET_DEST is the second > > > register in > > > a register pair, and SET_SRC is half of a vector register that > > > overlaps > > > the first register in the corresponding pair. So it looks as if > > > mode > > > needs to be considered there. > > > > Yes. > > > > > This helps: > > > > > > --- a/gcc/rtlanal.c > > > +++ b/gcc/rtlanal.c > > > @@ -1619,6 +1619,8 @@ set_noop_p (const_rtx set) > > > return 0; > > > src = SUBREG_REG (src); > > > dst = SUBREG_REG (dst); > > > + if (GET_MODE (src) != GET_MODE (dst)) > > > + return 0; > > > } > > > > > > but I'm not sure whether I'm not missing something about subreg > > > semantics in the first place. > > > > You probably should just see if both modes are the same number of > > hard > > registers? HARD_REGNO_NREGS. > > I've refined my patch as follows: > > --- a/gcc/rtlanal.c > +++ b/gcc/rtlanal.c > @@ -1619,6 +1619,11 @@ set_noop_p (const_rtx set) > return 0; > src = SUBREG_REG (src); > dst = SUBREG_REG (dst); > + if (REG_P (src) && HARD_REGISTER_P (src) && REG_P (dst) > + && HARD_REGISTER_P (dst) > + && hard_regno_nregs (REGNO (src), GET_MODE (src)) > + != hard_regno_nregs (REGNO (dst), GET_MODE (dst)))
(The "!" should align with the "h".) > + return 0; > } Looks good to me, thanks! > This also helps, and is less restrictive than my first variant. > Two questions, just for my understanding: > > 1) This mode confusion problem must never happen to pseudos, because, > unlike hard registers, pseudos must be always referred to in their > natural mode. Is this correct? Only hard registers can be accessed in more than one mode, yes. To access pseudos in another mode you need a subreg. > 2) Can there be a hypothetical machine, where modes XF and YF refer to > 64-bit and 128-bit register pairs respectively? This would cause > the mode confusion problem again. Is there anything in RTL > semantics that would prohibit existence of such modes? They would have to be the same hard register number as well. Not very likely, but I don't see why it couldn't happen theoretically. Segher