https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120439
--- Comment #7 from camel-cdr <camel-cdr at protonmail dot com> --- I suppose it's a question about the intrinsics contract. The intrinsics by them self don't expose register assignment and don't give you a way to control it. Consider the following: static vuint8m1_t bar(vuint8m1_t vd, vuint16m2_t v) { return __riscv_vnsrl_tu(vd, v, 3, 4); } vuint8m1_t baz(vuint16m2_t v) { return bar(__riscv_vreinterpret_u8m1(__riscv_vlmul_trunc_u16m1(v)), v); } this generates: baz: vsetivli zero,4,e8,m1,tu,ma vnsrl.wi v8,v8,3 ret bar() looks perfectly fine by it self, as does baz(), but together they produce the wrong tail policy. If this codegen is correct, there is an implied provenance that can't be subverted and only validated by reading every line of the called code. I initially used intrinsics because it was the quickest way to test this behavior and my understanding of the intrinsics is that I should get tail agnostic, if I specify tail agnostic. I wasn't able to produce a case where the autovectorizer produces this type of code when I tried today.