RISC-V: Fix RVV can change mode class bug
commite1817426e85f2181a97ac4f71a87baaa9645b1b5
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Tue, 19 Sep 2023 02:59:22 +0000 (19 10:59 +0800)
committerLehua Ding <lehua.ding@rivai.ai>
Tue, 19 Sep 2023 12:06:23 +0000 (19 20:06 +0800)
tree658dd172b79d208de57932041a96ea9ff9998ab1
parent005888670a1a0e26d818449a0fbbc5eb3541e303
RISC-V: Fix RVV can change mode class bug

After support the VLS mode conversion, current case triggers a latent bug that we are
lucky we didn't encounter.

This is a real bug in 'cprop_hardreg':

orig:RVVMF8BI,16,16
new:V32BI,32,0
during RTL pass: cprop_hardreg
auto.c: In function 'main':
auto.c:79:1: internal compiler error: in partial_subreg_p, at rtl.h:3186
   79 | }
      | ^
0x10979a7 partial_subreg_p(machine_mode, machine_mode)
        ../../../../gcc/gcc/rtl.h:3186
0x1723eda mode_change_ok
        ../../../../gcc/gcc/regcprop.cc:402
0x1724007 maybe_mode_change
        ../../../../gcc/gcc/regcprop.cc:436
0x172445d find_oldest_value_reg
        ../../../../gcc/gcc/regcprop.cc:489
0x172534d copyprop_hardreg_forward_1
        ../../../../gcc/gcc/regcprop.cc:808
0x1727017 cprop_hardreg_bb
        ../../../../gcc/gcc/regcprop.cc:1358
0x17272f7 execute
        ../../../../gcc/gcc/regcprop.cc:1425

When trying to do reg copy propagation between RVVMF8BI (precision = 16,16)
and V32BI (precision = 32,0).

The assertion failed in partial_subreg_p:
gcc_checking_assert (ordered_p (outer_prec, inner_prec));

In regcprop.cc:

  if (partial_subreg_p (orig_mode, new_mode))
    return false;

If orig_mode (RVVMF8BI) smaller than new_mode (V32BI), we don't do the hard reg propogation.
However, the 'partial_subreg_p' cause ICE since gcc_checking_assert (ordered_p (outer_prec, inner_prec)).

After analysis in aarch64.cc, they do careful block in 'TARGET_CAN_CHANGE_MODE_CLASS'.
So it's reasonable block regcprop when old mode size maybe_lt than new mode size since we won't do the
copy propgation.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_can_change_mode_class): Block unordered VLA and VLS modes.
gcc/config/riscv/riscv.cc