This patch enables VLS loops to be controlled by SELECT_VL/vsetvl.
In case we choose a VLS mode for a loop we could only do
fixed-size + epilogue before. With this patch such loops can be length
controlled as well.
As opposed to VLA length-controlled loops we need to make sure to not e
---
gcc/config/riscv/autovec.md | 11 +++++++++++
gcc/config/riscv/riscv-v.cc | 18 ++++++++++++++++--
.../riscv/rvv/autovec/param-autovec-mode.c | 2 +-
.../riscv/rvv/autovec/partial/select_vl-2.c | 4 +---
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index cac2ec6ad8b..c3c6da94a3c 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1345,6 +1345,17 @@ (define_expand "select_vl<V:mode><P:mode>"
DONE;
})
+(define_expand "select_vl<VLS:mode><P:mode>"
+ [(match_operand:P 0 "register_operand")
+ (match_operand:P 1 "vector_length_operand")
+ (match_operand:P 2 "immediate_operand")
+ (match_operand:VLS 3 "general_operand")]
+ "TARGET_VECTOR && TARGET_ZBB"
+{
+ riscv_vector::expand_select_vl (operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT,FP] Insert a vector element.
;; -------------------------------------------------------------------------
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4eae231a797..5ce725f7826 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -4470,8 +4470,22 @@ expand_select_vl (rtx *ops)
/* We arbitrary picked QImode as inner scalar mode to get vector mode.
since vsetvl only demand ratio. We let VSETVL PASS to optimize it. */
scalar_int_mode mode = QImode;
- machine_mode rvv_mode = get_vector_mode (mode, nunits).require ();
- emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1]));
+ machine_mode vector_mode = get_vector_mode (mode, nunits).require ();
+ if (riscv_vla_mode_p (vector_mode))
+ emit_insn (gen_no_side_effects_vsetvl_rtx (vector_mode, ops[0], ops[1]));
+ else
+ {
+ /* Emit
+ avl_adj = min (avl, nunits);
+ vsetvl (dest, avl_adj, ...); */
+ gcc_assert (TARGET_ZBB);
+ rtx nunits_reg = gen_reg_rtx (Pmode);
+ emit_move_insn (nunits_reg, GEN_INT (nunits.to_constant ()));
+ rtx avl_adj = gen_reg_rtx (Pmode);
+ emit_move_insn (avl_adj, simplify_gen_binary
+ (UMIN, Pmode, ops[1], nunits_reg));
+ emit_insn (gen_no_side_effects_vsetvl_rtx (vector_mode, ops[0],
avl_adj));
+ }
}
/* Return RVV_VUNDEF if the ELSE value is scratch rtx. */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c
index 1ee7eb32e37..56038428626 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/param-autovec-mode.c
@@ -13,4 +13,4 @@ foo (int *a, int *b, int n)
}
/* { dg-final { scan-tree-dump "Choosing vector mode V4QI" "vect" } } */
-/* { dg-final { scan-tree-dump "Choosing epilogue vector mode RVVM1SI" "vect"
} } */
+/* { dg-final { scan-tree-dump "operating on partial vectors." "vect" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
index a96e6ffa315..d485d78e980 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/select_vl-2.c
@@ -6,12 +6,10 @@
/*
** foo:
-**
vsetivli\t[a-x0-9]+,\s*8,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
+**
vsetivli\tzero,\s*4,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
-**
vsetvli\tzero,\s*[a-x0-9]+,\s*e(8?|16?|32?|64),\s*m(1?|2?|4?|8?|f2?|f4?|f8),\s*t[au],\s*m[au]
-** ...
** vle32\.v\tv[0-9]+,0\([a-x0-9]+\)
** ...
*/
--
2.51.0