From: Pan Li <pan2...@intel.com> 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 During vectorization the override_widen pattern matched and then will get DImode as vector_mode in loop_info. After that the loop_vinfo will step in vect_analyze_xx with below flow: vect_analyze_loop_2 |- vect_pattern_recog // over-widening and set loop_vinfo->vector_mode to DImode |- ... |- vect_analyze_loop_operations |- stmt_info->def_type == vect_reduction_def |- stmt_info->slp_type == pure_slp |- vectorizable_lc_phi // Not Hit |- vectorizable_induction // Not Hit |- vectorizable_reduction // Not Hit |- vectorizable_recurr // Not Hit |- vectorizable_live_operation // Not Hit |- vect_analyze_stmt |- stmt_info->relevant == vect_unused_in_scope |- stmt_info->live == false |- p pattern_stmt_info == (stmt_vec_info) 0x0 |- return opt_result::success (); OR |- PURE_SLP_STMT (stmt_info) && !node then dump "handled only by SLP analysis\n" |- Early return opt_result::success (); |- vectorizable_load/store/call_convert/... // Not Hit |- LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P && !LOOP_VINFO_MASKS(loop_vinfo).is_empty () |- vect_verify_loop_lens (loop_vinfo) |- assert (VECTOR_MODE_P (loop_vinfo->vector_mode); // Hit assert result in ICE Finally, the DImode in loop_vinfo will hit the assert (VECTOR_MODE_P (mode)) in vect_verify_loop_lens. This patch would like to return false directly if the loop_vinfo has relevant mode like DImode for the ICE fix, but still may have mis-optimization for similar cases. We will try to cover that in separated patches. The below test suites are passed for this patch. * The rv64gcv fully regression test. * The x86 bootstrap test. * The x86 fully regression test. PR middle-end/116351 gcc/ChangeLog: * tree-vect-loop.cc (vect_verify_loop_lens): Return false if the loop_vinfo has relevant mode such as DImode. 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 <pan2...@intel.com> --- .../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-loop.cc | 3 +++ 4 files changed, 31 insertions(+) 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/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-loop.cc b/gcc/tree-vect-loop.cc index 07b19a22d42..b279ebe2793 100644 --- a/gcc/tree-vect-loop.cc +++ b/gcc/tree-vect-loop.cc @@ -1562,6 +1562,9 @@ vect_verify_loop_lens (loop_vec_info loop_vinfo) if (LOOP_VINFO_LENS (loop_vinfo).is_empty ()) return false; + if (!VECTOR_MODE_P (loop_vinfo->vector_mode)) + return false; + machine_mode len_load_mode, len_store_mode; if (!get_len_load_store_mode (loop_vinfo->vector_mode, true) .exists (&len_load_mode)) -- 2.43.0