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

--- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, tried this under the debugger.  All VALID_MVE_PRED_MODE modes have the same
size, 2 bytes, so I'd go with
  else if (VALID_MVE_PRED_MODE (mode))
    {
      /* unsigned short arguments to functions get promoted to int, undo that. 
*/
      if (GET_MODE_SIZE (x) != GET_MODE_SIZE (HImode))
        x = gen_lowpart (HImode, x);
      if (GET_MODE (x) != mode)
        {
          /* Nested SUBREGs are invalid.  */
          if (SUBREG_P (x))
            x = force_reg (GET_MODE (x), x);
          x = lowpart_subreg (mode, x,
                              GET_MODE (x) == VOIDmode ? HImode : GET_MODE
(x));
        }
    }
It would surprise me if (subreg:V4BI (reg:SI 116 [ _3 ]) 0) gets through
validation given the differences in sizes, but if you really want to handle
that as before, then just:
  else if (VALID_MVE_PRED_MODE (mode))
    {
      if (GET_CODE (x) == CONST_INT)
        x = lowpart_subreg (mode, gen_lowpart (HImode, x), HImode);
      else if (GET_MODE (x) != mode)
        {
          if (SUBREG_P (x))
            x = force_reg (GET_MODE (x), x);
          x = gen_lowpart (mode, x);
        }
    }
i.e. use lowpart_subreg on gen_lowpart on CONST_INTs (gen_lowpart effectively
does
lowpart_subreg (HImode, x, DImode) in that case), the force_reg case to avoid
ICEs if say (subreg:SI (reg:DI ...) 0) is passed and gen_lowpart as before.

Reply via email to