From: Pan Li <[email protected]>
This patch would like to fix the ICE similar as below, assump we have
sample code:
1 │ int a, b, c;
2 │ short d, e, f;
3 │ long g (long h) { return h; }
4 │
5 │ void i () {
6 │ for (; b; ++b) {
7 │ f = 5 >> a ? d : d << a;
8 │ e &= c | g(f);
9 │ }
10 │ }
It will ice when compile with -O3 -march=rv64gc_zve64f -mrvv-vector-bits=zvl
during GIMPLE pass: vect
pr116351-1.c: In function ‘i’:
pr116351-1.c:8:6: internal compiler error: in get_len_load_store_mode,
at optabs-tree.cc:655
8 | void i () {
| ^
0x44d6b9d internal_error(char const*, ...)
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/diagnostic-global-context.cc:517
0x44a26a6 fancy_abort(char const*, int, char const*)
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/diagnostic.cc:1722
0x19e4309 get_len_load_store_mode(machine_mode, bool, internal_fn*,
vec<int, va_heap, vl_ptr>*)
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/optabs-tree.cc:655
0x1fada40 vect_verify_loop_lens
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:1566
0x1fb2b07 vect_analyze_loop_2
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:3037
0x1fb4302 vect_analyze_loop_1
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:3478
0x1fb4e9a vect_analyze_loop(loop*, gimple*, vec_info_shared*)
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/tree-vect-loop.cc:3638
0x203c2dc try_vectorize_loop_1
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/tree-vectorizer.cc:1095
0x203c839 try_vectorize_loop
/home/pli/gcc/111/riscv-gnu-toolchain/gcc/__RISC-V_BUILD__/../gcc/tree-vectorizer.cc:1212
0x203cb2c execute
The zve32x cannot have 64 elen, and then the get_related_vectype_for_scalar_type
will get DImode as vector_mode in loop_info. After that the underlying
vect_analyze_xx will assert the mode is VECTOR and then ICE at the assert.
The fix contains 2 part, aka let the get_related_vectype_for_scalar_type
return NULL_TREE if mode_for_vector is not VECTOR mode in the middle-end,
and then mark the innermode of RVV is DImode is not support when the
TARGET_VECTOR_ELEN_64 is false.
The below test suites are passed for this patch.
* The rv64gcv fully regression test.
* The x86 bootstrap test.
* The x86 fully regression test.
PR target/116351
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_vector_mode_supported_any_target_p): Mark
innnermode of RVV is DImode unsupported when zve32*.
* tree-vect-stmts.cc (get_related_vectype_for_scalar_type): Return
the NULL_TREE if mode_for_vector is not a VECTOR mode.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/base/pr116351-1.c: New test.
* gcc.target/riscv/rvv/base/pr116351-2.c: New test.
* gcc.target/riscv/rvv/base/pr116351.h: New test.
Signed-off-by: Pan Li <[email protected]>
---
gcc/config/riscv/riscv.cc | 6 +++++-
.../gcc.target/riscv/rvv/base/pr116351-1.c | 5 +++++
.../gcc.target/riscv/rvv/base/pr116351-2.c | 5 +++++
.../gcc.target/riscv/rvv/base/pr116351.h | 18 ++++++++++++++++++
gcc/tree-vect-stmts.cc | 9 +++++++--
5 files changed, 40 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr116351.h
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9bf7713139f..89b534ac88f 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12613,10 +12613,14 @@ extract_base_offset_in_addr (rtx mem, rtx *base, rtx
*offset)
/* Implements target hook vector_mode_supported_any_target_p. */
static bool
-riscv_vector_mode_supported_any_target_p (machine_mode)
+riscv_vector_mode_supported_any_target_p (machine_mode mode)
{
if (TARGET_XTHEADVECTOR)
return false;
+
+ if (GET_MODE_INNER (mode) == DImode && !TARGET_VECTOR_ELEN_64)
+ return false;
+
return true;
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-1.c
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-1.c
new file mode 100644
index 00000000000..f58fedfeaf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-1.c
@@ -0,0 +1,5 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32x -mabi=lp64d -O3 -ftree-vectorize" } */
+
+#include "pr116351.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-2.c
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-2.c
new file mode 100644
index 00000000000..e1f46b745e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351-2.c
@@ -0,0 +1,5 @@
+/* Test that we do not have ice when compile */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f -mabi=lp64d -O3 -ftree-vectorize" } */
+
+#include "pr116351.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351.h
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351.h
new file mode 100644
index 00000000000..25bd0ec65e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr116351.h
@@ -0,0 +1,18 @@
+#ifndef PR116351_H
+#define PR116351_H
+
+#define T long
+
+int a, b, c;
+short d, e, f;
+
+T g (T h) { return h; }
+
+void i () {
+ for (; b; ++b) {
+ f = 5 >> a ? d : d << a;
+ e &= c | g(f);
+ }
+}
+
+#endif
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 6bbb16beff2..a4a959185da 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -14228,8 +14228,13 @@ get_related_vectype_for_scalar_type (machine_mode
prevailing_mode,
Note that nunits == 1 is allowed in order to support single
element vector types. */
- if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, &nunits)
- || !mode_for_vector (inner_mode, nunits).exists (&simd_mode))
+ if (!multiple_p (GET_MODE_SIZE (simd_mode), nbytes, &nunits))
+ return NULL_TREE;
+
+ bool exist_p = mode_for_vector (inner_mode,
+ nunits).exists (&simd_mode);
+
+ if (!exist_p || (exist_p && !VECTOR_MODE_P (simd_mode)))
return NULL_TREE;
}
}
--
2.43.0