Hello,

On Tue, 30 Jun 2026, Richard Biener wrote:

> > The call chain for our testcase is the following:
> > gen_lowpart -> gen_lowpart_general -> gen_lowpart_common -> lowpart_subreg 
> > -> simplify_gen_subreg -> validate_subreg.
> >
> > `validate_subreg` for OI and V4x4BF modes fails, leading to this fallback 
> > in `gen_lowpart_general`:
> >
> > /* Handle SUBREGs and hard REGs that were rejected by
> >      simplify_gen_subreg.  */
> >   else if (REG_P (x) || GET_CODE (x) == SUBREG)
> >     {
> >       result = gen_lowpart_common (mode, copy_to_reg (x));
> >       gcc_assert (result != 0);
> >       return result;
> >     }
> >
> > `copy_to_reg (x)` creates the new reg.
> 
> And what's 'x' here?  That said, either gen_lowpart () isn't supposed to 
> be used in lvalue context

This.  It cannot just generally be used on the LHS, for exactly the reason 
we see here: it may generate a new reg (on the unchecked but commented 
assumption that the input was a hardreg that was invalid for the wanted 
mode), which would require copy-back.  FWIW, this was the original comment 
for gen_lowpart_general() before 2004:

  /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
     return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
     least-significant part of X.  ... */

N.B: "value".  Not LHS.  That comment was unfortunately lost.  All uses of 
gen_lowpart (which translates to calling gen_lowpart_general) on the LHS 
are dubious at best, but also pre-existing and some of them are _very_ 
old.  That this was harmless indicates that most of the time, in the 
circumstances that they are called (here for instance, with target mode 
being an int_mode_for_mode), they aren't going the copy_to_reg path, and 
hence return a proper normal subreg of the input rtx.

So, the question hence is: _why_ does validate_subreg fail on that mode 
combination OI/V4x4BF, if this is supposed to be the int_mode_for_mode on 
that target?  I guess that should just be fixed.

The more correct change would be to generally just use 
gen_lowpart_if_possible on LHSs, but then the callers need to be able to 
deal with the fact that it may return NULL.  But ... that will be larger 
:)


Ciao,
Michael.

Reply via email to