[gcc r14-6135] RISC-V: Add blocker for gather/scatter auto-vectorization

Pan Li panli@gcc.gnu.org
Tue Dec 5 07:57:59 GMT 2023


https://gcc.gnu.org/g:8b93a0f3eb46cbc4ba8eece8eba58aaade4399b6

commit r14-6135-g8b93a0f3eb46cbc4ba8eece8eba58aaade4399b6
Author: Juzhe-Zhong <juzhe.zhong@rivai.ai>
Date:   Tue Dec 5 11:22:50 2023 +0800

    RISC-V: Add blocker for gather/scatter auto-vectorization
    
    This patch fixes ICE exposed on full coverage testing:
    
                                    === g++: Unexpected fails for rv64gc_zve32f_zvfh_zfh lp64d medlow --param=riscv-autovec-lmul=dynamic ===
    FAIL: g++.dg/pr106219.C  -std=gnu++14 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++17 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++20 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++98 (internal compiler error: in require, at machmode.h:313)
                                    === g++: Unexpected fails for rv64gc_zve32f_zvfh_zfh lp64d medlow --param=riscv-autovec-lmul=dynamic --param=riscv-autovec-preference=fixed-vlmax ===
    FAIL: g++.dg/pr106219.C  -std=gnu++14 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++17 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++20 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++98 (internal compiler error: in require, at machmode.h:313)
                                    === g++: Unexpected fails for rv64gc_zve32f_zvfh_zfh lp64d medlow --param=riscv-autovec-lmul=m4 ===
    FAIL: g++.dg/pr106219.C  -std=gnu++14 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++17 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++20 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++98 (internal compiler error: in require, at machmode.h:313)
                                    === g++: Unexpected fails for rv64gc_zve32f_zvfh_zfh lp64d medlow --param=riscv-autovec-lmul=m4 --param=riscv-autovec-preference=fixed-vlmax ===
    FAIL: g++.dg/pr106219.C  -std=gnu++14 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++17 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++20 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++98 (internal compiler error: in require, at machmode.h:313)
                                    === g++: Unexpected fails for rv64gc_zve32f_zvfh_zfh lp64d medlow --param=riscv-autovec-lmul=m8 ===
    FAIL: g++.dg/pr106219.C  -std=gnu++14 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++17 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++20 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++98 (internal compiler error: in require, at machmode.h:313)
                                    === g++: Unexpected fails for rv64gc_zve32f_zvfh_zfh lp64d medlow --param=riscv-autovec-lmul=m8 --param=riscv-autovec-preference=fixed-vlmax ===
    FAIL: g++.dg/pr106219.C  -std=gnu++14 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++17 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++20 (internal compiler error: in require, at machmode.h:313)
    FAIL: g++.dg/pr106219.C  -std=gnu++98 (internal compiler error: in require, at machmode.h:313)
    
    The rootcause is we can't extend RVVM4SImode into RVVM8DImode on zve32f.
    Add a blocker of it to disable such auto-vectorization in this situation.
    
    gcc/ChangeLog:
    
            * config/riscv/autovec.md: Add blocker.
            * config/riscv/riscv-protos.h (gather_scatter_valid_offset_p): New function.
            * config/riscv/riscv-v.cc (gather_scatter_valid_offset_p): Ditto.
    
    gcc/testsuite/ChangeLog:
    
            * g++.target/riscv/rvv/autovec/bug-2.C: New test.

Diff:
---
 gcc/config/riscv/autovec.md                        | 24 ++++++++++----------
 gcc/config/riscv/riscv-protos.h                    |  1 +
 gcc/config/riscv/riscv-v.cc                        | 18 +++++++++++++++
 gcc/testsuite/g++.target/riscv/rvv/autovec/bug-2.C | 26 ++++++++++++++++++++++
 4 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 2d727c2609b..b9f7aa204da 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -59,7 +59,7 @@
    (match_operand:<RATIO64:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO64I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, true);
   DONE;
@@ -74,7 +74,7 @@
    (match_operand:<RATIO32:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO32I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, true);
   DONE;
@@ -89,7 +89,7 @@
    (match_operand:<RATIO16:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO16I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, true);
   DONE;
@@ -104,7 +104,7 @@
    (match_operand:<RATIO8:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO8I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, true);
   DONE;
@@ -119,7 +119,7 @@
    (match_operand:<RATIO4:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO4I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, true);
   DONE;
@@ -134,7 +134,7 @@
    (match_operand:<RATIO2:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO2I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, true);
   DONE;
@@ -172,7 +172,7 @@
    (match_operand:<RATIO64:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO64I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, false);
   DONE;
@@ -187,7 +187,7 @@
    (match_operand:<RATIO32:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO32I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, false);
   DONE;
@@ -202,7 +202,7 @@
    (match_operand:<RATIO16:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO16I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, false);
   DONE;
@@ -217,7 +217,7 @@
    (match_operand:<RATIO8:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO8I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, false);
   DONE;
@@ -232,7 +232,7 @@
    (match_operand:<RATIO4:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO4I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, false);
   DONE;
@@ -247,7 +247,7 @@
    (match_operand:<RATIO2:VM> 5 "vector_mask_operand")
    (match_operand 6 "autovec_length_operand")
    (match_operand 7 "const_0_operand")]
-  "TARGET_VECTOR"
+  "TARGET_VECTOR && riscv_vector::gather_scatter_valid_offset_p (<RATIO2I:MODE>mode)"
 {
   riscv_vector::expand_gather_scatter (operands, false);
   DONE;
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 695ee24ad6f..bfbd2bf0d18 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -606,6 +606,7 @@ enum vlmul_type get_vlmul (rtx_insn *);
 int count_regno_occurrences (rtx_insn *, unsigned int);
 bool imm_avl_p (machine_mode);
 bool can_be_broadcasted_p (rtx);
+bool gather_scatter_valid_offset_p (machine_mode);
 }
 
 /* We classify builtin types into two classes:
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 588c127343e..dd659f99f91 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -4686,4 +4686,22 @@ emit_vec_extract (rtx target, rtx src, poly_int64 index)
     emit_move_insn (target, ops[0].value);
 }
 
+/* Return true if the offset mode is valid mode that we use for gather/scatter
+   autovectorization.  */
+bool
+gather_scatter_valid_offset_p (machine_mode mode)
+{
+  /* If the element size of offset mode is already >= Pmode size,
+     we don't need any extensions.  */
+  if (known_ge (GET_MODE_SIZE (GET_MODE_INNER (mode)), UNITS_PER_WORD))
+    return true;
+
+  /* Since we are very likely extend the offset mode into vector Pmode,
+     Disable gather/scatter autovectorization if we can't extend the offset
+     mode into vector Pmode.  */
+  if (!get_vector_mode (Pmode, GET_MODE_NUNITS (mode)).exists ())
+    return false;
+  return true;
+}
+
 } // namespace riscv_vector
diff --git a/gcc/testsuite/g++.target/riscv/rvv/autovec/bug-2.C b/gcc/testsuite/g++.target/riscv/rvv/autovec/bug-2.C
new file mode 100644
index 00000000000..53bc4a30072
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/rvv/autovec/bug-2.C
@@ -0,0 +1,26 @@
+/* { dg-options "-march=rv64gc_zve32f -mabi=lp64d -O3 --param=riscv-autovec-lmul=m4" } */
+
+int max(int __b) {
+  if (0 < __b)
+    return __b;
+  return 0;
+}
+struct Plane {
+  Plane(int, int);
+  int *Row();
+};
+float *ConvolveXSampleAndTranspose_rowp;
+int ConvolveXSampleAndTranspose_res, ConvolveXSampleAndTranspose_r;
+void ConvolveXSampleAndTranspose() {
+  Plane out(0, ConvolveXSampleAndTranspose_res);
+  for (int y;;) {
+    float sum;
+    for (int i = ConvolveXSampleAndTranspose_r; i; ++i)
+      sum += i;
+    for (; ConvolveXSampleAndTranspose_r; ++ConvolveXSampleAndTranspose_r)
+      sum +=
+          ConvolveXSampleAndTranspose_rowp[max(ConvolveXSampleAndTranspose_r)] *
+          ConvolveXSampleAndTranspose_r;
+    out.Row()[y] = sum;
+  }
+}


More information about the Gcc-cvs mailing list