<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/79665>79665</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
RISCV __riscv_vsetvl() and __riscv_vsetvlmax() intrinsics fail to inform optimiser about return constraints
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
sh1boot
</td>
</tr>
</table>
<pre>
By wrapping the intrinsic `__riscv_vsetvlmax_u8m1()` in a function which exposes some additional details about the behaviour of the operations, like so:
```C
__attribute__((const)) inline size_t get_vlmax_u8m1() {
size_t vlmax = __riscv_vsetvlmax_e8m1();
#if defined __riscv_v_fixed_vlen
constexpr size_t fixed_vl = __riscv_v_fixed_vlen / 8;
if (vlmax != fixed_vl) __builtin_unreachable();
#else
constexpr size_t min_vl = __riscv_v_min_vlen / 8;
if (vlmax < min_vl) __builtin_unreachable();
#endif
return vlmax;
}
__attribute__((const)) inline size_t set_vl_u8m1(size_t avl) {
size_t vl = __riscv_vsetvl_e8m1(avl);
#if defined __riscv_v_fixed_vlen
constexpr size_t fixed_vl = __riscv_v_fixed_vlen / 8;
if (avl <= fixed_vl && vl != avl) __builtin_unreachable();
if (avl >= fixed_vl * 2 && vl != fixed_vl) __builtin_unreachable();
#else
constexpr size_t min_vl = __riscv_v_min_vlen / 8;
if (avl <= min_vl && vl != avl) __builtin_unreachable();
#endif
return vl;
}
```
The optimiser can then use this knowledge to elide more dead code. For example:
```C
inline void generic(void* data, size_t len) {
uint8_t* ptr = reinterpret_cast<uint8_t*>(data);
size_t vl = get_vlmax_u8m1();
vuint8m1_t zero = __riscv_vmv_v_x_u8m1(0, vl);
while (len > vl) {
__riscv_vse8(ptr, zero, vl);
ptr += vl;
len -= vl;
}
__riscv_vse8(ptr, zero, len);
}
inline void generic2(void* data, size_t len) {
uint8_t* ptr = reinterpret_cast<uint8_t*>(data);
size_t vl = set_vl_u8m1(len);
while (len > 0) {
vuint8m1_t zero = __riscv_vmv_v_x_u8m1(0, vl);
__riscv_vse8(ptr, zero, vl);
ptr += vl;
len -= vl;
vl = set_vl_u8m1(len);
}
}
void u64_wrapper(uint64_t& data) {
generic(&data, sizeof(data));
}
void u64_wrapper2(uint64_t& data) {
generic2(&data, sizeof(data));
}
void generic_wrapper(void* data, size_t len) {
generic(data, len);
}
void generic_wrapper2(void* data, size_t len) {
generic2(data, len);
}
```
The hints allow the `u64_wrapper()` functions to emit trivial, straight-through code with no loops. Removing the hints makes these functions perform unnecessary tests and loops.
I'm not 100% sure I defined the hints correctly, but something like that. Knowledge of the target might help further.
Perhaps these hints could be embedded in the intrinsics themselves?
https://godbolt.org/z/P4z9a5jjT
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMV01v2zgQ_TX0ZZBApmzFPvjQJDVQ7KXoFnsVKHFksaVIgRzZSX79grQUy7LbNOgC2yBIYGs-3sx7HA2F92pnEDdsec-WjzPRUW3dxtfzwlqaFVY-b-6f4eBE2yqzA6oRlCGnjFclsCzJc6d8uc_3HmmvG_GUd6tmzviK8TXLElAGBFSdKUlZA4dalTXgU2s9evC2QRBSqvBMaJBIQmkPorAdxVQF1mKvbOfAVvEL26ITwdwz_gBafUfwlqUfWPLIkg8sS46_D8fPkOeCyKmiI8zzCGpVWuMpgONrUEYrg-DVC-YEO6R8WgKwu_s-FsBgGI2ApY9wWT2eqk97z_4vT1UFEitlUJ4c80o9ocz3Gk2fJwLEp9YN6QaL84wjR2B8C6vXfAGpqoDxVQ-Uz4PnYB-qyvOiU5qUyTvjUJS1KDROYfMUtcdTzAtgjTKXsI5fvg0qfej934PHSFWNmxqiOqTOmSMpJ-O7xzO7dwnBRyEMKui_FEek1_VwRQyDEo5-f4AYRHR6GEsBGM8Yz2IBR5GIX-djGvnjJPIH4Jfx_xQRjpoxBPiNVrwpzSu6HEbV2OdrnHCkGuXRQSlMmHkGOo9AtfLw3diDRrlDIAuolURorEOQKCSUVuItwNY6wCfRtBpPc_HqdOxFv7dKwg4NOlWG42mVDORJQSLM2L7NQZJT-XfK0CqnYN2SixQ4VIbQtQ4pL4Unlj6crIJG-OoYeKSj81N0bQqfEbiPAZt5TvCCzp4z3wT2X12TUMD5-QsRDrXSGFQQFZJ-hOnRHp3kMClaciFQyHY9YPiJHeD3Ac2I7-FpyHQzffYqhmDx85zH9v9ovF1hkv8vVF7MxPNROqnikojkAth_w_jbDX4XqVfZHMD-SuEAJ_InXEYSu2yRx50LHeOrUH62CH3Pei4nTTqdXsazMdu2GrH0Y_1Mc_I3k45U9hsp-yijUt8h2VPRg_HPD8m1jO88JaOq38z5o_leK0MehNb2EDdaliXnbPeL87Az-zjrG0VATu2V0BEjOaF2Nd1Q7Wy3q-Pwh4OiGowFbW3rbwG-YGP3w9Z-zNuI7-jDZ4-jDC26yroGOmOwRO-FewZCH3Aa2Ycb1_GJ8bsGjCWYJwnjS_CdQ_j0utCc8pXWOSxJPwfURUdx56c6gIrLO9WCbgH-en2x9Xs-CbfD8HLf1QQ16haqzlGN7gzHZ3S1aId6hoydllAgYFOglCjDFeTs2hLtG496j56l23HAmqj14bXJt4xvd1YWVtOtdTvGty-Mbz8vXtZi-e3b15ncpHKdrsUMN_O7JEvn8_lqOas3qzVfIl-u06Tky3V2l8hyOS9wna6qNMFiPVMbnvBFMucZT-frxeK2WqQLsU7nMkmzNMsKtkiwEUrfar1vQu6Z8r7Dzd06y5YzLQrUPl7XODd4gPiQcR5ub24TfG6KbufZItHKkz9FIUUaN18-_f3wz2RV7a86geuLC03_bNS8SigdNKlM1MxpXzle2_qdJ-5pTgRKZp3Tm0lnFdVdcVvahvFtQNj_u2md_YYlMb6NdXnGt7HufwMAAP__R-51ig">