Vect: Fix ICE when vect_verify_loop_lens acts on relevant mode [PR116351]

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.li@intel.com>
This commit is contained in:
Pan Li 2025-02-19 09:37:51 +08:00
parent 427386042f
commit 25256ec1df
4 changed files with 31 additions and 0 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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

View file

@ -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))