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.

Reply via email to