diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index cc27a76c44f..fc5a31c9396 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -419,9 +419,18 @@ (match_operand 1 "")] "TARGET_VECTOR" { - /* Expand into a QImode vector. */ - machine_mode qimode = riscv_vector::get_vector_mode + /* Expand into a QImode vector. + For XTheadVector which does not have fractional-LMUL modes, we use + a full-size vector instead. */ + bool fractional_p = known_lt (GET_MODE_NUNITS (mode), + BYTES_PER_RISCV_VECTOR); + machine_mode qimode; + if (!TARGET_XTHEADVECTOR || !fractional_p) + qimode = riscv_vector::get_vector_mode (QImode, GET_MODE_NUNITS (mode)).require (); + else + qimode = riscv_vector::get_m1_mode + (QImode, GET_MODE_NUNITS (mode).is_constant ()).require (); rtx tmp = gen_reg_rtx (qimode); riscv_vector::expand_vec_init (tmp, operands[1]); @@ -433,7 +442,12 @@ riscv_vector::emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops); /* Compare against zero. */ - riscv_vector::expand_vec_cmp (operands[0], NE, tmp2, CONST0_RTX (qimode)); + rtx op0; + if (!TARGET_XTHEADVECTOR || !fractional_p) + op0 = operands[0]; + else + op0 = gen_lowpart (riscv_vector::get_mask_mode (qimode), operands[0]); + riscv_vector::expand_vec_cmp (op0, NE, tmp2, CONST0_RTX (qimode)); DONE; } ) @@ -1449,15 +1463,30 @@ [(match_operand 2 "nonmemory_operand")])))] "TARGET_VECTOR" { - /* Create an empty byte vector and set it to one under mask. */ - machine_mode qimode = riscv_vector::get_vector_mode - (QImode, GET_MODE_NUNITS (mode)).require (); + /* Create an empty byte vector and set it to one under mask. + For XTheadVector which does not have fractional-LMUL modes, we use + a full-size vector instead. */ + bool fractional_p = known_lt (GET_MODE_NUNITS (mode), + BYTES_PER_RISCV_VECTOR); + machine_mode qimode; + if (!TARGET_XTHEADVECTOR || !fractional_p) + qimode = riscv_vector::get_vector_mode + (QImode, GET_MODE_NUNITS (mode)).require (); + else + qimode = riscv_vector::get_m1_mode + (QImode, GET_MODE_NUNITS (mode).is_constant ()).require (); rtx tmp1 = gen_reg_rtx (qimode); emit_move_insn (tmp1, gen_const_vec_duplicate (qimode, GEN_INT (0))); rtx ones = gen_const_vec_duplicate (qimode, GEN_INT (1)); - rtx ops1[] = {tmp1, tmp1, ones, operands[1]}; + rtx op1; + if (!TARGET_XTHEADVECTOR || !fractional_p) + op1 = operands[1]; + else + op1 = gen_lowpart (riscv_vector::get_mask_mode (qimode), operands[1]); + + rtx ops1[] = {tmp1, tmp1, ones, op1}; riscv_vector::emit_vlmax_insn (code_for_pred_merge (qimode), riscv_vector::MERGE_OP, ops1); diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 0734c31ec56..dd029c70413 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -653,6 +653,7 @@ enum tail_policy get_prefer_tail_policy (); enum mask_policy get_prefer_mask_policy (); rtx get_avl_type_rtx (enum avl_type); opt_machine_mode get_lmul_mode (scalar_mode, int); +opt_machine_mode get_m1_mode (machine_mode, bool = false); opt_machine_mode get_vector_mode (scalar_mode, poly_uint64); opt_machine_mode get_tuple_mode (machine_mode, unsigned int); bool simm5_p (rtx); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 29dc3ebccd6..82313356a80 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2281,14 +2281,19 @@ get_lmul_mode (scalar_mode mode, int lmul) return E_VOIDmode; } -/* Return the appropriate M1 mode for MODE. */ +/* Return the appropriate LMUL1 mode for MODE. + If VLS_P is specified, get a VLS mode that represents a full + vector. */ -static opt_machine_mode -get_m1_mode (machine_mode mode) +opt_machine_mode +get_m1_mode (machine_mode mode, bool vls_p) { scalar_mode smode = GET_MODE_INNER (mode); unsigned int bytes = GET_MODE_SIZE (smode); - poly_uint64 m1_nunits = exact_div (BYTES_PER_RISCV_VECTOR, bytes); + poly_uint64 bytes_vector = BYTES_PER_RISCV_VECTOR; + if (vls_p) + bytes_vector = constant_lower_bound (bytes_vector); + poly_uint64 m1_nunits = exact_div (bytes_vector, bytes); return get_vector_mode (smode, m1_nunits); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr124147.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr124147.c new file mode 100644 index 00000000000..2233a18f4c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr124147.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mcpu=xt-c920 -mrvv-vector-bits=zvl" } */ + +typedef __attribute__((__vector_size__(2 * sizeof(int)))) int V; + +V +foo(V v) +{ + return v > 0; +} +