Thanks Richard.

> so the obvious fix would be to add
>
> if (!VECTOR_MODE_P (loop_vinfo->vector_mode))
>    return false;

I also think of it, but it is too "easy" and then dropped.

> Ah, it needs -march=rv64imd_xsfvcp.  

It can also be reproduced by " -march=rv64imd_zve32x  -mrvv-vector-bits=zvl", 
sorry forgot to mention this.

> The error is probably that vect_verify_loop_lens does not do anything
> to ensure the checks are done on a relevant mode.  With the suggested
> added check above this then becomes a missed optimization rather
> than an ICE.  But it might fall apart if there's not one load/store len mode
> to consider?

I see, it may fall apart I am afraid, consider RVVM1DImode when rv64gc_zve32x,
the riscv_vector_mode_supported_any_target_p will always return true and we may
have RVVM1DImode here but zve32x cannot support DI as element size.

I will try to reproduce this after this ICE fix.

Pan


-----Original Message-----
From: Richard Biener <richard.guent...@gmail.com> 
Sent: Tuesday, February 18, 2025 5:36 PM
To: Li, Pan2 <pan2...@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; kito.ch...@gmail.com; 
jeffreya...@gmail.com; rdapp....@gmail.com
Subject: Re: [PATCH v1] Vect: Fix ICE when get DImode from 
get_related_vectype_for_scalar_type [PR116351]

On Tue, Feb 18, 2025 at 10:12 AM Richard Biener
<richard.guent...@gmail.com> wrote:
>
> On Tue, Feb 18, 2025 at 9:40 AM Li, Pan2 <pan2...@intel.com> wrote:
> >
> > Hi Richard,
> >
> > After some more investigation, the sample code never hit one vectorizable_* 
> > routines which may check the loop_vinfo->vector_mode,
> > and then the loop_vinfo->vector_mode == DImode will hit the 
> > vect_verify_loop_lens and trigger the assert VECTOR_MODE_P, detail
> > flow as below.
> >
> > vect_analyze_loop_2
> >  |- vect_pattern_recog // Hit over-widening pattern and set 
> > loop_vinfo->vector_mode to DImode
> >  |- ...
> >  |- vect_analyze_loop_operations
> >    |- (gdb) p stmt_info->def_type
> >    |- $1 = vect_reduction_def
> >    |- (gdb) p stmt_info->slp_type
> >    |- $2 = 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
> >      |- (gdb) p stmt_info->relevant
> >      |- $3 = vect_unused_in_scope
> >      |- (gdb) p stmt_info->live
> >      |- $4 = false
> >      |- (gdb) p pattern_stmt_info
> >      |- $5 = (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
> >
> > I am a little hesitant by two options here.
> >
> > 1. shall we add some condition and dump log here to make the 
> > vect_analyze_loop_2 failure when loop_vinfo->vector_mode is not supported 
> > vector mode by target.
> > 2. it should not be LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P here? Then we need 
> > to find out where set the partial vector to true.
> >
> > Is there any suggestion here?
>
> static bool
> vect_verify_loop_lens (loop_vec_info loop_vinfo)
> {
>   if (LOOP_VINFO_LENS (loop_vinfo).is_empty ())
>     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))
>     return false;
>
> so the obvious fix would be to add
>
>   if (!VECTOR_MODE_P (loop_vinfo->vector_mode))
>     return false;
>
> here?  But then I wonder how we got to a DImode vector_mode and record
> a loop len
> in the first place.  I could imagine we first end up with DImode but
> other stmts using
> a vector mode and we record a len for those.  But then the above
> get_len_load_store_mode
> on ->vector_mode seems to assume that all modes we need a len for are
> "compatible" with ->vector_mode so I assume recording a LEN would check that.
>
> I can't reproduce the ICE with a cross on trunk btw.

Ah, it needs -march=rv64imd_xsfvcp.  So we indeed call vect_record_loop_len
with

(gdb) p debug_tree (vectype)
 <vector_type 0x7ffff71bd1f8
    type <integer_type 0x7ffff7017690 short int public HI
        size <integer_cst 0x7ffff7041558 constant 16>
        unit-size <integer_cst 0x7ffff7041570 constant 2>
        align:16 warn_if_not_align:0 symtab:0 alias-set 2
canonical-type 0x7ffff7017690 precision:16 min <integer_cst
0x7ffff7041510 -32768> max <integer_cst 0x7ffff7041528 32767>
        pointer_to_this <pointer_type 0x7ffff71b4348>>
    RVVM2HI
(gdb) p loop_vinfo->vector_mode
$2 = E_DImode

from vectorizable_operation and ->vector_mode is set via
vect_recog_over_widening_pattern which commits to a DImode
vector type ->vector_mode prematurely.

The error is probably that vect_verify_loop_lens does not do anything
to ensure the checks are done on a relevant mode.  With the suggested
added check above this then becomes a missed optimization rather
than an ICE.  But it might fall apart if there's not one load/store len mode
to consider?

>
> Richard.
>
> >
> > Pan
> >
> > -----Original Message-----
> > From: Li, Pan2
> > Sent: Monday, February 17, 2025 6:08 PM
> > To: Richard Biener <richard.guent...@gmail.com>
> > Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; kito.ch...@gmail.com; 
> > jeffreya...@gmail.com; rdapp....@gmail.com
> > Subject: RE: [PATCH v1] Vect: Fix ICE when get DImode from 
> > get_related_vectype_for_scalar_type [PR116351]
> >
> > > But that's wrong - read the comment before the code.  We do support 
> > > integer mode
> > > "generic" vectorization just fine.  Iff there's anything to plug then
> > > it's how we end
> > > up thinking there's with_len support for DImode vectors.
> >
> > I see, then we need another place to fix this, let me have a try.
> >
> > Pan
> >
> > -----Original Message-----
> > From: Richard Biener <richard.guent...@gmail.com>
> > Sent: Monday, February 17, 2025 6:02 PM
> > To: Li, Pan2 <pan2...@intel.com>
> > Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; kito.ch...@gmail.com; 
> > jeffreya...@gmail.com; rdapp....@gmail.com
> > Subject: Re: [PATCH v1] Vect: Fix ICE when get DImode from 
> > get_related_vectype_for_scalar_type [PR116351]
> >
> > On Mon, Feb 17, 2025 at 10:38 AM <pan2...@intel.com> wrote:
> > >
> > > 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
> > >
> > > 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 <pan2...@intel.com>
> > > ---
> > >  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)))
> >
> > But that's wrong - read the comment before the code.  We do support integer 
> > mode
> > "generic" vectorization just fine.  Iff there's anything to plug then
> > it's how we end
> > up thinking there's with_len support for DImode vectors.
> >
> > Richard.
> >
> > >             return NULL_TREE;
> > >         }
> > >      }
> > > --
> > > 2.43.0
> > >

Reply via email to