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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
set_noop_p is clearly buggy here, expecting a constant selector

  /* It is a NOOP if destination overlaps with selected src vector
     elements.  */
  if (GET_CODE (src) == VEC_SELECT
      && REG_P (XEXP (src, 0)) && REG_P (dst)
      && HARD_REGISTER_P (XEXP (src, 0))
      && HARD_REGISTER_P (dst))
    {
      int i;
      rtx par = XEXP (src, 1);
      rtx src0 = XEXP (src, 0);
      poly_int64 c0 = rtx_to_poly_int64 (XVECEXP (par, 0, 0));
      poly_int64 offset = GET_MODE_UNIT_SIZE (GET_MODE (src0)) * c0;

      for (i = 1; i < XVECLEN (par, 0); i++)
        if (maybe_ne (rtx_to_poly_int64 (XVECEXP (par, 0, i)), c0 + i))
          return 0;
      return
        REG_CAN_CHANGE_MODE_P (REGNO (dst), GET_MODE (src0), GET_MODE (dst))
        && simplify_subreg_regno (REGNO (src0), GET_MODE (src0),
                                  offset, GET_MODE (dst)) == (int) REGNO (dst);
    }

both for c0 and the XVECEXP in the loop it needs to check whether it actually
is a constant.  Like via poly_int_rtx_p.  A patch like along that line
is pre-approved.  Broken since introduction of that code
in commit 8c8952918b75

Reply via email to