This patch adds else operands to masked loads. Currently the default else operand predicate accepts "undefined" (i.e. SCRATCH) as well as all-ones values.
Note that this series introduces a large number of new RVV FAILs for riscv. All of them are due to us not being able to elide redundant vec_cond_exprs. PR 115336 PR 116059 gcc/ChangeLog: * config/riscv/autovec.md: Add else operand. * config/riscv/predicates.md (maskload_else_operand): New predicate. * config/riscv/riscv-v.cc (get_else_operand): Remove static. (expand_load_store): Use get_else_operand and adjust index. (expand_gather_scatter): Ditto. (expand_lanes_load_store): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr115336.c: New test. * gcc.target/riscv/rvv/autovec/pr116059.c: New test. --- gcc/config/riscv/autovec.md | 45 +++++++++++-------- gcc/config/riscv/predicates.md | 3 ++ gcc/config/riscv/riscv-v.cc | 26 +++++++---- .../gcc.target/riscv/rvv/autovec/pr115336.c | 20 +++++++++ .../gcc.target/riscv/rvv/autovec/pr116059.c | 9 ++++ 5 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr115336.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116059.c diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index d5793acc999..4111474309c 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -26,8 +26,9 @@ (define_expand "mask_len_load<mode><vm>" [(match_operand:V 0 "register_operand") (match_operand:V 1 "memory_operand") (match_operand:<VM> 2 "vector_mask_operand") - (match_operand 3 "autovec_length_operand") - (match_operand 4 "const_0_operand")] + (match_operand:V 3 "maskload_else_operand") + (match_operand 4 "autovec_length_operand") + (match_operand 5 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_load_store (operands, true); @@ -57,8 +58,9 @@ (define_expand "mask_len_gather_load<RATIO64:mode><RATIO64I:mode>" (match_operand 3 "<RATIO64:gs_extension>") (match_operand 4 "<RATIO64:gs_scale>") (match_operand:<RATIO64:VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO64I:MODE>mode)" { riscv_vector::expand_gather_scatter (operands, true); @@ -72,8 +74,9 @@ (define_expand "mask_len_gather_load<RATIO32:mode><RATIO32I:mode>" (match_operand 3 "<RATIO32:gs_extension>") (match_operand 4 "<RATIO32:gs_scale>") (match_operand:<RATIO32:VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO32I:MODE>mode)" { riscv_vector::expand_gather_scatter (operands, true); @@ -87,8 +90,9 @@ (define_expand "mask_len_gather_load<RATIO16:mode><RATIO16I:mode>" (match_operand 3 "<RATIO16:gs_extension>") (match_operand 4 "<RATIO16:gs_scale>") (match_operand:<RATIO16:VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO16I:MODE>mode)" { riscv_vector::expand_gather_scatter (operands, true); @@ -102,8 +106,9 @@ (define_expand "mask_len_gather_load<RATIO8:mode><RATIO8I:mode>" (match_operand 3 "<RATIO8:gs_extension>") (match_operand 4 "<RATIO8:gs_scale>") (match_operand:<RATIO8:VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO8I:MODE>mode)" { riscv_vector::expand_gather_scatter (operands, true); @@ -117,8 +122,9 @@ (define_expand "mask_len_gather_load<RATIO4:mode><RATIO4I:mode>" (match_operand 3 "<RATIO4:gs_extension>") (match_operand 4 "<RATIO4:gs_scale>") (match_operand:<RATIO4:VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO4I:MODE>mode)" { riscv_vector::expand_gather_scatter (operands, true); @@ -132,8 +138,9 @@ (define_expand "mask_len_gather_load<RATIO2:mode><RATIO2I:mode>" (match_operand 3 "<RATIO2:gs_extension>") (match_operand 4 "<RATIO2:gs_scale>") (match_operand:<RATIO2:VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO2I:MODE>mode)" { riscv_vector::expand_gather_scatter (operands, true); @@ -151,8 +158,9 @@ (define_expand "mask_len_gather_load<mode><mode>" (match_operand 3 "<gs_extension>") (match_operand 4 "<gs_scale>") (match_operand:<VM> 5 "vector_mask_operand") - (match_operand 6 "autovec_length_operand") - (match_operand 7 "const_0_operand")] + (match_operand 6 "maskload_else_operand") + (match_operand 7 "autovec_length_operand") + (match_operand 8 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_gather_scatter (operands, true); @@ -280,8 +288,9 @@ (define_expand "vec_mask_len_load_lanes<mode><vsingle>" [(match_operand:VT 0 "register_operand") (match_operand:VT 1 "memory_operand") (match_operand:<VM> 2 "vector_mask_operand") - (match_operand 3 "autovec_length_operand") - (match_operand 4 "const_0_operand")] + (match_operand 3 "maskload_else_operand") + (match_operand 4 "autovec_length_operand") + (match_operand 5 "const_0_operand")] "TARGET_VECTOR" { riscv_vector::expand_lanes_load_store (operands, true); diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 9971fabc587..7cc7c2b1f9d 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -528,6 +528,9 @@ (define_predicate "autovec_else_operand" (ior (match_operand 0 "register_operand") (match_operand 0 "scratch_operand"))) +(define_predicate "maskload_else_operand" + (match_operand 0 "scratch_operand")) + (define_predicate "vector_arith_operand" (ior (match_operand 0 "register_operand") (and (match_code "const_vector") diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index d74c4723abc..ed40e768500 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -3818,12 +3818,23 @@ expand_select_vl (rtx *ops) emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1])); } +/* Return RVV_VUNDEF if the ELSE value is scratch rtx. */ +static rtx +get_else_operand (rtx op) +{ + return GET_CODE (op) == SCRATCH ? RVV_VUNDEF (GET_MODE (op)) : op; +} + /* Expand MASK_LEN_{LOAD,STORE}. */ void expand_load_store (rtx *ops, bool is_load) { - rtx mask = ops[2]; - rtx len = ops[3]; + int idx = 2; + rtx mask = ops[idx++]; + /* A masked load has a merge/else operand. */ + if (is_load) + get_else_operand (ops[idx++]); + rtx len = ops[idx]; machine_mode mode = GET_MODE (ops[0]); if (is_vlmax_len_p (mode, len)) @@ -3916,13 +3927,6 @@ expand_cond_len_op (unsigned icode, insn_flags op_type, rtx *ops, rtx len) emit_nonvlmax_insn (icode, insn_flags, ops, len); } -/* Return RVV_VUNDEF if the ELSE value is scratch rtx. */ -static rtx -get_else_operand (rtx op) -{ - return GET_CODE (op) == SCRATCH ? RVV_VUNDEF (GET_MODE (op)) : op; -} - /* Expand unary ops COND_LEN_*. */ void expand_cond_len_unop (unsigned icode, rtx *ops) @@ -4043,6 +4047,8 @@ expand_gather_scatter (rtx *ops, bool is_load) int shift; rtx mask = ops[5]; rtx len = ops[6]; + if (is_load) + len = ops[7]; if (is_load) { vec_reg = ops[0]; @@ -4265,6 +4271,8 @@ expand_lanes_load_store (rtx *ops, bool is_load) { rtx mask = ops[2]; rtx len = ops[3]; + if (is_load) + len = ops[4]; rtx addr = is_load ? XEXP (ops[1], 0) : XEXP (ops[0], 0); rtx reg = is_load ? ops[0] : ops[1]; machine_mode mode = GET_MODE (ops[0]); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr115336.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr115336.c new file mode 100644 index 00000000000..29e55705a7a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr115336.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options { -O3 -march=rv64gcv_zvl256b -mabi=lp64d } } */ + +short d[19]; +_Bool e[100][19][19]; +_Bool f[10000]; + +int main() +{ + for (long g = 0; g < 19; ++g) + d[g] = 3; + _Bool(*h)[19][19] = e; + for (short g = 0; g < 9; g++) + for (int i = 4; i < 16; i += 3) + f[i * 9 + g] = d[i] ? d[i] : h[g][i][2]; + for (long i = 120; i < 122; ++i) + __builtin_printf("%d\n", f[i]); +} + +/* { dg-final { scan-assembler-times {vmv.v.i\s*v[0-9]+,0} 3 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116059.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116059.c new file mode 100644 index 00000000000..55e03c5ec0b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr116059.c @@ -0,0 +1,9 @@ +char a; +_Bool b[11] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +int main() { + _Bool *c = b; + for (signed d = 0; d < 11; d += 1) + a = d % 2 == 0 ? c[d] / c[d] + : c[d]; + __builtin_printf("%u\n", a); +} -- 2.45.2