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

--- Comment #12 from Robin Dapp <rdapp at gcc dot gnu.org> ---
Some "findings" below but I don't have the feeling I'm much closer to anything
actionable.

At some point we're trying to split a live range of an RVVM8QI register (v16,
hard regno = 112) for the reload insn

(insn 93 169 123 2 (set (reg:RVVM8QI 169 [orig:135 _4 ] [135])
        (reg:RVVM8QI 241 [orig:135 _4 ] [135])) "pr115458.c":48:33 2726
{*movrvvm8qi_whole}
     (nil))

In split_reg we have
      mode = RVVM8QI
but
      machine_mode reg_rtx_mode = GET_MODE (regno_reg_rtx[hard_regno]);

However reg_raw_mode[112] = RVVM1SF so
      reg_rtx_mode = RVVM1SF.

As an RVVM8QI access to RVVM1SF constitutes a paradoxical subreg we change the
mode to RVVM1SF and eventually create a spill/save

(insn 174 0 0 (set (reg:RVVM1SF 247)
        (reg:RVVM1SF 112 v16)) -1
     (nil))

This happens for all hard regs of RVVM8QI individually (v16 - v23), same for
the restore of course.

As a data point: When prohibiting this mode change and just keeping RVVM8QI we
compile successfully and we barely need to reload at all.

However, reg_rtx_mode[112] = RVVM1SF without the vector ABI so, while odd, it's
not the real culprit.

Reply via email to