<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/114518>114518</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Lack of vsetvli after function call for whole register move
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:RISC-V
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          kito-cheng
      </td>
    </tr>
</table>

<pre>
    Unfortunately, whole register move instructions depend on `vtype`*1, which means they will cause an illegal instruction exception if VILL=1. This is generally not a problem, as VILL is set to 0 after any valid `vsetvli` instruction, so it’s usually safe unless the user executes a whole vector register move very early in the program.

However, the situation changed after the Linux kernel applied a patch[2] that sets VILL=1 after any system call. So, if we try to execute a whole register move after a system call, it will cause an illegal instruction exception. This can be difficult to detect, as the system call may not be invoked immediately; it might be deeply nested in a call chain, such as within `printf`. Unfortunately, this change has already shipped with Linux kernel 6.5, which was released on August 28, 2023.

I'm not sure if it's reasonable to ask the Linux kernel maintainers to fix this by keeping VILL consistent across system calls.

An alternative approach is to address this issue on the toolchain side by requiring at least one valid `vsetvli` instruction before any whole register move. This might be an ugly workaround, but it’s probably the simplest way to resolve the issue. I also realized this might be a better solution since the psABI specifies that `VTYPE` is NOT preserved across function calls. This means we can’t guarantee that VILL is not 1 at the function entry, so placing a `vsetvli` instruction right after the function call may be necessary.


Testcase:
```c
#include <riscv_vector.h>
void bar() __attribute__((riscv_vector_cc));

vint32m1_t foo(vint32m1_t a) {
    bar();  // We never know bar will call system call inside or not.
    return a;
}
```

Generated asm with `clang -target riscv64-unknown-elf -S -O3 -march=rv64gcv`:
```asm
...
        .type   foo,@function
        .variant_cc     foo
foo:                                    # @foo
# %bb.0:                                # %entry
        addi    sp, sp, -16
        sd      ra, 8(sp)                       # 8-byte Folded Spill
        vmv1r.v v24, v8
        call    bar
        vmv1r.v v8, v24
        ld      ra, 8(sp)                       # 8-byte Folded Reload
        addi    sp, sp, 16
        ret
...
```

And the compiler could emits code like below to fix this issue:

```asm
...
        .type   foo,@function
        .variant_cc     foo
foo:                                    # @foo
# %bb.0:                                # %entry
        addi    sp, sp, -16
        sd      ra, 8(sp)                       # 8-byte Folded Spill
        vsetivli x0, 0, e8, m1, ta, ma   # Need vsetvli to make VILL=0 here
        vmv1r.v v24, v8
        call    bar
        vsetivli x0, 0, e8, m1, ta, ma  # Need vsetvli to make VILL=0 here
        vmv1r.v v8, v24
        ld      ra, 8(sp)                       # 8-byte Folded Reload
        addi    sp, sp, 16
        ret
...
```

NOTE: We have hit this issue within our internal spec run.

`*1` That change[1] is made *AFTER* 1.0...
[1] https://github.com/riscvarchive/riscv-v-spec/commit/856fe5bd1cb135c39258e6ca941bf234ae63e1b1  
[2] https://github.com/torvalds/linux/commit/9657e9b7d2538dc73c24947aa00a8525dfb8062c
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsV0-P27oR_zT0ZWBDoiz_OfjgzWbbAEFSJNs89LQYkSOLNUWqJCWv--kLUtq1vQmSV7z2UKCGIVvicOY3M78ZjtB7dTBEO1besfJ-hn1orNsdVbBz0ZA5zCorz7u_mtq60BsMpM-Mv4NTYzWBo4PygRy0diBQxgfXi6Cs8SCpIyPBGmCrbAjnjtgqY3yfj7uVaKAlNB5CQ2c4Ka1BYO8J0IDSmg6orxUCPQvq0j9Vw7cPHz-y4j5fwGOjPCgPBzLkUOszGBsAoXO20tRGY-iTfJTyFCBYyADriBrNGQbUSiaMnsKgFVtl13ajAm9BBfaes03GtlsPve-TJY81QW80-eQF9J4c0DOJPpAHnGI0kAjWvQnVQO4MhE6fQZm0uXP24LBdsOyeZfvx-md7ooFcxBBFvAo9phCIBs2B5ORGXPuoTP8MR3KGNGDXaRWXocMgGlbecVbeQ2gwxBD41_hdxcGffaAWBGq9gK822lQ1nAiCO8eYTX69unXrz6TnWkvSEP6dzE7ZFGigIpCqrpXodcqYpEAiTNlMsbgYghbHrFeRgoM9kgTVtiTVyNbiLuJo1aFJIpKoizQhH6KgARy1iAbVmO5eNNHMSYVGJfp2TplQs1W2gO8KISTIKR_QoAfUjlCewTeq60gmLbfZWS3KSw2c0IMjTegpFcu-P_Q-AN9EEZ7x4oYQHxhft8lX3zuKCVKB8XVUgd4arDTFaKE_fk-KFpUJqAw5H2Vq9Txir85wJOqUOYxlIqzxMbMmAApnvb-Otb-BszeAOpAzGFQkQdc5i6KJlRZRSOnG0kgl6nuKDkZcwVqdwg1eSYoIHP2jVy5iwAAxGgGsoV8VJ1RUW0eJvz9g5cSn18yjgf6gz3Cy7ojO9kbGIFd9uC3v2Dqw0uep5tpOkw9wwlQGjrzVA6W15NMCPgBqH1dQq3-SHP29GIWKQkTkre4TaK-MGBV0fn_3AXxHQtWK_FigbJV9e_zbX94nXz18-vwInSNPbogVPWak7s0YgDEnk5-pnZ4oFtCrOwEOPTo0gWhU_9IKI4nyGO0I5FUfmeDOU8_rNIqUkZ8kwCU3L23oBlgqzIrAkCDv0Z1vyDNeH8kHgZ5Y8fJ4lY1fMd3zQhmhe0nAindOeTE8jS110bDi_Sg0WCWhQsdi3Wzh6QlDcKrqAz09pWeb641PQjC-jd_i7hrLoEwoeJs_BaitZXxz9QCjXrae5AHgYi42GGD8gfEH-C16O5CDo7GnKPLS_7S-aVnKJOZbF_OwuCh1FHpnAC_I1vdv4nKN-E_p1It9DH07tpoYOY3mAPOA7kABkuer5bw3EZOZk65h_hXmnwuYt-hEw4p7N6yWBzFE7d_lAX07PlksroDGzyKe6gBjsN6xZfaS_TdiAzqFJjwJke6jeBKIf4pXsZ99GC8g6n_Zme55WVWL7HdomKRHbt9AQylV_PVd4ny6zvPVrZCX46_DuBzJFAW3PzG2mVfnQPBgtSQJXzul9a3KoR1ytxhg4Muoc9jcLieKTBT78b50PMTdN8v6DyL9Qtqi_HWI3kbIUXhDkR-ydW9kahLCtp3S5EDYXkugVgUPwkoCrY4EFWl7ujmiUqO9MPP__Pyv89NTUINW8JxFnelCiXNtmt9DMtXipO8TkYTphIiJa_FILzNmBg05-g_R_3fD-kOo_ieL69Pnx_eRa7_FMXQgaFS4nrymYdb2DpRJI5tOgwe43ize1lV8S1tl8BjnhXG0ZeVdHl8h4piB8Sjm-_3D4_svjO8hX2QXaJNcE0LnY8WmY_GgQtNXC2Fbxh_SeRTPHTXQy-18mEcwjD8I27Zxpn3YlKuaykrmosqLUhRbXm5oJXC7zKuaF0ukVUF5lQO8Wua_sBysG1BLz_iDjpPxtbntqlzTtlpLXhYbKdaF4Mvtco2YZbgpeSnrapOtuJjJXSG3xRZntMvXRbZcbsqcz5qdKDNEKcWmWm-3VV4u14XM83WJ5bqWG1HN1I5nfJnnWZ5tsk3BF3y7oaxYVXVdrSusOFtm1KLSC62HdmHdYZZSt8vzZZlvZhor0j69p3NeoTiSkazYf_nw9d38G-PR-Znbxb3zqj94tsy08sFftAUVNO0-ojiCrV8LY5zdbue22rofzdOz3undT-IbLU0_887Zv6c3tofkRIz55Mew4_8KAAD___TP9KU">