O
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index c0293a306f9..e8a728ae226 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -219,6 +219,7 @@ rtx gen_avl_for_scalar_move (rtx);
> void expand_tuple_move (machine_mode, rtx *);
> machine_mode preferred_simd_mode (scalar_mode);
> opt_machine_mode get_mask_mode (machine_mode);
> +void expand_vec_series (rtx, rtx, rtx);
> }
>
> /* We classify builtin types into two classes:
> diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
> index 7ca49ca67c1..0c3b1b4c40b 100644
> --- a/gcc/config/riscv/riscv-v.cc
> +++ b/gcc/config/riscv/riscv-v.cc
> @@ -248,6 +248,111 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src,
> rtx len,
> emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false);
> }
>
> +/* Emit binary operations. */
> +
> +static void
> +emit_binop (unsigned icode, rtx *ops, machine_mode mask_mode,
> + machine_mode scalar_mode)
> +{
> + insn_expander<9> e;
> + machine_mode mode = GET_MODE (ops[0]);
> + e.add_output_operand (ops[0], mode);
> + e.add_all_one_mask_operand (mask_mode);
> + e.add_vundef_operand (mode);
> + if (VECTOR_MODE_P (GET_MODE (ops[1])))
> + e.add_input_operand (ops[1], GET_MODE (ops[1]));
> + else
> + e.add_input_operand (ops[1], scalar_mode);
> + if (VECTOR_MODE_P (GET_MODE (ops[2])))
> + e.add_input_operand (ops[2], GET_MODE (ops[2]));
> + else
> + e.add_input_operand (ops[2], scalar_mode);
> + rtx vlmax = gen_reg_rtx (Pmode);
> + emit_vlmax_vsetvl (mode, vlmax);
> + e.add_input_operand (vlmax, Pmode);
> + e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy
> ());
> + e.add_avl_type_operand (avl_type::VLMAX);
> + e.expand ((enum insn_code) icode, false);
> +}
> +
> +/* Emit vid.v instruction. */
> +
> +static void
> +emit_indexop (rtx target, machine_mode mask_mode)
nit: rename to emit_index_op
> +void
> +expand_vec_series (rtx dest, rtx base, rtx step)
> +{
> + machine_mode mode = GET_MODE (dest);
> + machine_mode inner_mode = GET_MODE_INNER (mode);
> + machine_mode mask_mode;
> + gcc_assert (get_mask_mode (mode).exists (&mask_mode));
> +
> + /* VECT_IV = BASE + I * STEP. */
> +
> + /* Step 1: Generate I = { 0, 1, 2, ... } by vid.v. */
> + rtx tmp = gen_reg_rtx (mode);
> + emit_indexop (tmp, mask_mode);
> + if (rtx_equal_p (step, const1_rtx) && rtx_equal_p (base, const0_rtx))
> + {
> + emit_move_insn (dest, tmp);
> + return;
> + }
> +
> + /* Step 2: Generate I * STEP.
> + - STEP is 1, we don't emit any instructions.
> + - STEP is power of 2, we use vsll.vi/vsll.vx.
> + - STEP is non-power of 2, we use vmul.vx. */
The comment seems mismatch the structure of the code, I am prefer to
restructure the code to match the comment.
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/series-1.c
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/series-1.c
> new file mode 100644
> index 00000000000..a01f6ce7411
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/series-1.c
> @@ -0,0 +1,50 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gcv -mabi=ilp32d --param
> riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4" } */
> +
> +#include <stdint.h>
Use stdint-gcc.h instead