RISC-V: Allow simplification non-vlmax with len = NUNITS reg to reg move
V2: Address comments from Robin.
While working on fixing a bug, I notice this following code has redundant move:
#include "riscv_vector.h"
void
f (float x, float y, void *out)
{
float f[4] = { x, x, x, y };
vfloat32m1_t v = __riscv_vle32_v_f32m1 (f, 4);
__riscv_vse32_v_f32m1 (out, v, 4);
}
Before this patch:
f:
vsetivli zero,4,e32,m1,ta,ma
addi sp,sp,-16
vfmv.v.f v1,fa0
vfslide1down.vf v1,v1,fa1
vmv.v.v v1,v1 ----> redundant move.
vse32.v v1,0(a0)
addi sp,sp,16
jr ra
The rootcause is that the complicate vmv.v.v pattern doesn't simplify it
into simple (set (reg) (reg)) reg-to-reg move pattern.
Currently, we support such simplification for VLMAX.
However, the case I found is non-VLMAX but with LEN = NUNITS which should be
considered as equivalent to VLMAX.
Add a simple fix for such situation.
Tested on both RV32/RV64 no regressions.
gcc/ChangeLog:
* config/riscv/riscv-protos.h (whole_reg_to_reg_move_p): New function.
* config/riscv/riscv-v.cc (whole_reg_to_reg_move_p): Ditto.
* config/riscv/vector.md: Allow non-vlmax with len = NUNITS simplification.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/base/vf_avl-4.c: New test.