Eric Botcazou <ebotca...@adacore.com> writes:
>> FWIW I agree this is the right approach, although I can't approve it.
>> The assert above is guarding code that deals with a very general case,
>> including some unusual combinations, so I don't think it would be a
>> good idea to try to remove it entirely.
>
> Yes, but the patch is a bit of kludge since it short-circuits the meat of the 
> function:
>
>    /* This should always pass, otherwise we don't know how to verify
>      the constraint.  These conditions may be relaxed but
>      subreg_regno_offset would need to be redesigned.  */
>   gcc_assert ((GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)) == 0);
>   gcc_assert ((nregs_xmode % nregs_ymode) == 0);
>
> So what would it take to do things properly here, i.e. relax the conditions 
> and adjust downstream?

What do you think we should relax it to though?  Obviously there's a balance
here between relaxing things enough and not relaxing them too far (so that
the EImode AArch64 thing I mentioned is still a noisy failure, for example).
ISTM the patch deals with the only significant case that is obviously safe
for modes that are not a power of 2 in size.

If you're saying that the condition itself is OK, but that the code should
be further down in the function, then I don't think that would gain much.
We already have early-outs for the simple cases, such as:

  /* Paradoxical subregs are otherwise valid.  */
  if (!rknown
      && offset == 0
      && GET_MODE_PRECISION (ymode) > GET_MODE_PRECISION (xmode))
    {
      info->representable_p = true;
      /* If this is a big endian paradoxical subreg, which uses more
         actual hard registers than the original register, we must
         return a negative offset so that we find the proper highpart
         of the register.  */
      if (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
          ? REG_WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN)
        info->offset = nregs_xmode - nregs_ymode;
      else
        info->offset = 0;
      info->nregs = nregs_ymode;
      return;
    }
  [...]
  /* Lowpart subregs are otherwise valid.  */
  if (!rknown && offset == subreg_lowpart_offset (ymode, xmode))
    {
      info->representable_p = true;
      rknown = true;

      if (offset == 0 || nregs_xmode == nregs_ymode)
        {
          info->offset = 0;
          info->nregs = nregs_ymode;
          return;
        }
    }

which also come before the assert.

Thanks,
Richard

Reply via email to