Hi, when the destination register of a vmv.x.s needs to be sign extended to XLEN we currently emit an sext insn. Since vmv.x.s performs this implicitly this patch adds two instruction patterns (intended for combine et al.) that include sign_extend for the destination operand.
The tests extend the vec_extract tests sent before. Regards Robin gcc/ChangeLog: * config/riscv/vector-iterators.md: Add VI_QH iterator. * config/riscv/autovec-opt.md (@pred_extract_first_sextdi<mode>): New vmv.x.s pattern that includes sign extension. (@pred_extract_first_sextsi<mode>): Dito for SImode. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c: Expect no sext instructions. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c: Dito. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c: Dito. * gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c: Dito. --- gcc/config/riscv/autovec-opt.md | 29 +++++++++++++++++++ gcc/config/riscv/vector-iterators.md | 5 ++++ .../rvv/autovec/vls-vlmax/vec_extract-1.c | 2 ++ .../rvv/autovec/vls-vlmax/vec_extract-2.c | 2 ++ .../rvv/autovec/vls-vlmax/vec_extract-3.c | 2 ++ .../rvv/autovec/vls-vlmax/vec_extract-4.c | 2 ++ 7 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 7bb93eed220..82bd967dc38 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -330,3 +330,32 @@ (define_insn_and_split "*zero_sign_extend_fma" } [(set_attr "type" "viwmuladd") (set_attr "mode" "<V_DOUBLE_TRUNC>")]) + +;; ------------------------------------------------------------------------- +;; ---- Sign-extension for vmv.x.s. +;; ------------------------------------------------------------------------- +(define_insn "@pred_extract_first_sextdi<mode>" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI + (unspec:<VEL> + [(vec_select:<VEL> + (match_operand:VI_QHS 1 "register_operand""vr") + (parallel [(const_int 0)])) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)))] + "TARGET_VECTOR && Pmode == DImode" + "vmv.x.s\t%0,%1" + [(set_attr "type" "vimovvx") + (set_attr "mode" "<MODE>")]) + +(define_insn "@pred_extract_first_sextsi<mode>" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI + (unspec:<VEL> + [(vec_select:<VEL> + (match_operand:VI_QH 1 "register_operand" "vr") + (parallel [(const_int 0)])) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)))] + "TARGET_VECTOR && Pmode == SImode" + "vmv.x.s\t%0,%1" + [(set_attr "type" "vimovvx") + (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 6abd777c1ad..e8b39d63d28 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -352,6 +352,11 @@ (define_mode_iterator VFULLI [ (VNx2DI "TARGET_FULL_V") (VNx4DI "TARGET_FULL_V") (VNx8DI "TARGET_FULL_V") (VNx16DI "TARGET_FULL_V") ]) +(define_mode_iterator VI_QH [ + (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") + (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") +]) + (define_mode_iterator VI_QHS [ (VNx1QI "TARGET_MIN_VLEN < 128") VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32") (VNx128QI "TARGET_MIN_VLEN >= 128") (VNx1HI "TARGET_MIN_VLEN < 128") VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32") (VNx64HI "TARGET_MIN_VLEN >= 128") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c index b631fdb9cc6..dedd56a3d3b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-1.c @@ -47,3 +47,5 @@ TEST_ALL1 (VEC_EXTRACT) /* { dg-final { scan-assembler-times {\tvfmv.f.s} 5 } } */ /* { dg-final { scan-assembler-times {\tvmv.x.s} 13 } } */ + +/* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c index 0a93752bd4b..f63cee4c2a4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-2.c @@ -56,3 +56,5 @@ TEST_ALL2 (VEC_EXTRACT) /* { dg-final { scan-assembler-times {\tvfmv.f.s} 9 } } */ /* { dg-final { scan-assembler-times {\tvmv.x.s} 19 } } */ + +/* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c index 24c39168578..d8e0b78f5a2 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-3.c @@ -57,3 +57,5 @@ TEST_ALL3 (VEC_EXTRACT) /* { dg-final { scan-assembler-times {\tvfmv.f.s} 9 } } */ /* { dg-final { scan-assembler-times {\tvmv.x.s} 19 } } */ + +/* { dg-final { scan-assembler-not {\tsext} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c index e3d29cab628..25bd5c92fc3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/vec_extract-4.c @@ -58,3 +58,5 @@ TEST_ALL4 (VEC_EXTRACT) /* { dg-final { scan-assembler-times {\tvfmv.f.s} 9 } } */ /* { dg-final { scan-assembler-times {\tvmv.x.s} 20 } } */ + +/* { dg-final { scan-assembler-not {\tsext} } } */ -- 2.40.1