https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112401
Bug ID: 112401 Summary: RISC-V: So many redundant move instructions due to subreg handling on vector mode Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: juzhe.zhong at rivai dot ai Target Milestone: --- Consider this following case: https://godbolt.org/z/8nc6r4joc Compare with LLVM, we have so many redundant move instruction "vmv1r" #include <riscv_vector.h> void subreg_to_reg_1 (int32_t *in, int32_t *out, size_t m) { vint32m8_t result = __riscv_vle32_v_i32m8 (in, 32); vint32m1_t v0 = __riscv_vget_v_i32m8_i32m1 (result, 0); vint32m1_t v1 = __riscv_vget_v_i32m8_i32m1 (result, 1); vint32m1_t v2 = __riscv_vget_v_i32m8_i32m1 (result, 2); vint32m1_t v3 = __riscv_vget_v_i32m8_i32m1 (result, 3); vint32m1_t v4 = __riscv_vget_v_i32m8_i32m1 (result, 4); vint32m1_t v5 = __riscv_vget_v_i32m8_i32m1 (result, 5); vint32m1_t v6 = __riscv_vget_v_i32m8_i32m1 (result, 6); vint32m1_t v7 = __riscv_vget_v_i32m8_i32m1 (result, 7); for (size_t i = 0; i < m; i++) { v0 = __riscv_vadd_vv_i32m1(v0, v0, 4); v1 = __riscv_vadd_vv_i32m1(v1, v1, 4); v2 = __riscv_vadd_vv_i32m1(v2, v2, 4); v3 = __riscv_vadd_vv_i32m1(v3, v3, 4); v4 = __riscv_vadd_vv_i32m1(v4, v4, 4); v5 = __riscv_vadd_vv_i32m1(v5, v5, 4); v6 = __riscv_vadd_vv_i32m1(v6, v6, 4); v7 = __riscv_vadd_vv_i32m1(v7, v7, 4); } *(vint32m1_t*)(out+4*0) = v0; *(vint32m1_t*)(out+4*1) = v1; *(vint32m1_t*)(out+4*2) = v2; *(vint32m1_t*)(out+4*3) = v3; *(vint32m1_t*)(out+4*4) = v4; *(vint32m1_t*)(out+4*5) = v5; *(vint32m1_t*)(out+4*6) = v6; *(vint32m1_t*)(out+4*7) = v7; } Such issue not only happens on RISC-V but also in all other targets. Lehua will send a patch to support subreg liveness tracking on GCC soon.