diff mbox series

[8/8] RISC-V: Add else operand to masked loads [PR115536].

Message ID D3DDVOQRHY0E.1CILGBGAPE43D@gmail.com
State New
Headers show
Series [1/8] docs: Document maskload else operand and behavior. | expand

Commit Message

Robin Dapp Aug. 11, 2024, 9:01 p.m. UTC
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

Comments

Jeff Law Aug. 12, 2024, 5:59 p.m. UTC | #1
On 8/11/24 3:01 PM, Robin Dapp wrote:
> 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.
The RISC-V bits are fine.

jeff
diff mbox series

Patch

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);
+}