On Tue, Dec 9, 2025 at 5:59 AM Robin Dapp <[email protected]> wrote: > > Hi, > > In the PR we ICE accessing the loop lens in > vect_get_loop_variant_data_ptr_increment when building 510.parest. > This function only gets called when we use SELECT_VL for the loop > control, however during initialization of the loop lens partial > vectors, a prerequisite for SELECT_VL, was false while using_select_vl > was true. We reset using_partial_vectors when restarting the analysis > after forcing single-lane SLP but don't reset using_select_vl. > > This patch resets it as well. > > The test is a bit nasty due to all the warnings from -fpermissive. > For now I just captured all of them via dg-warning but maybe there's a > better way? > > Regards > Robin > > PR tree-optimization/123074 > > gcc/ChangeLog: > > * tree-vect-loop.cc: Reset LOOP_VINFO_USING_SELECT_VL_P. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/autovec/pr123074.C: New test. > --- > .../gcc.target/riscv/rvv/autovec/pr123074.C | 124 ++++++++++++++++++ > gcc/testsuite/gcc.target/riscv/rvv/rvv.exp | 2 +- > gcc/tree-vect-loop.cc | 1 + > 3 files changed, 126 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123074.C > > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123074.C > b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123074.C > new file mode 100644 > index 00000000000..f7b0655de91 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123074.C > @@ -0,0 +1,124 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -march=rv64gcv_zvl256b -mrvv-vector-bits=zvl > -mrvv-max-lmul=m2 -fpermissive -Wno-return-type" } */ > + > +namespace std { > +template <typename _Iterator> _Iterator __miter_base(_Iterator); > +template <typename _Default, typename, template <typename> class> > +struct __detector { > + using type = _Default; > +}; > +template <typename _Default, template <typename> class _Op> > +using __detected_or = __detector<_Default, void, _Op>; > +template <typename _Default, template <typename> class _Op> > +using __detected_or_t = typename __detected_or<_Default, _Op>::type; > +template <typename _Tp> class allocator { > +public: > + typedef _Tp value_type; > +}; > +template <typename> struct pointer_traits { > + template <typename _Up> using rebind = _Up *; > +}; > +} // namespace std > +namespace __gnu_cxx { > +template <typename _Iterator, typename> class __normal_iterator { > +public: > + _Iterator base(); > +}; > +} // namespace __gnu_cxx > +namespace std { > +template <bool, typename _OutIter, typename _InIter> > +void __assign_one(_OutIter __out, _InIter __in) { > + *__out = *__in; > +} > +template <bool _IsMove, typename _BI1, typename _BI2> > +__copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) { /* { > dg-warning "with no type" "" } */ > + while (__first != __last) { > + --__last; > + --__result; > + __assign_one<_IsMove>(__result, __last); > + } > +} > +template <bool _IsMove, typename _BI1, typename _BI2> > +__copy_move_backward_a1(_BI1 __first, _BI1 __last, _BI2 __result) { /* { > dg-warning "with no type" "" } */ > + __copy_move_backward_a2<_IsMove>(__first, __last, __result); > +} > +template <bool _IsMove, typename _II, typename _OI> > +__copy_move_backward_a(_II __first, _II __last, _OI __result) { /* { > dg-warning "with no type" "" } */ > + __copy_move_backward_a1<_IsMove>(__first, __last, __result); > +} > +template <typename _BI1, typename _BI2> > +move_backward(_BI1 __first, _BI1 __last, _BI2 __result) { /* { dg-warning > "with no type" "" } */ > + __copy_move_backward_a<true>(__first, __miter_base(__last), __result); > +} > +struct __allocator_traits_base { > + template <typename _Tp> using __pointer = typename _Tp::pointer; > + template <typename _Tp> using __c_pointer = typename _Tp::const_pointer; > +}; > +template <typename _Alloc> struct allocator_traits : __allocator_traits_base > { > + typedef typename _Alloc::value_type value_type; > + using pointer = __detected_or_t<value_type *, __pointer>; > + template <template <typename> class, typename _Tp> struct _Ptr { > + using type = typename pointer_traits<pointer>::rebind<_Tp>; > + }; > + using const_pointer = typename _Ptr<__c_pointer, value_type>::type; > +}; > +} // namespace std > +namespace __gnu_cxx { > +template <typename _Alloc> > +struct __alloc_traits : std::allocator_traits<_Alloc> {}; > +} // namespace __gnu_cxx > +namespace std { > +template <typename, typename _Alloc> struct _Vector_base { > + typedef __gnu_cxx::__alloc_traits<_Alloc> _Tp_alloc_type; > + typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer > pointer; > + struct { > + pointer _M_finish; > + } _M_impl; > +}; > +template <typename _Tp, typename _Alloc = allocator<_Tp>> > +class vector : _Vector_base<_Tp, _Alloc> { > + typedef _Vector_base<_Tp, _Alloc> _Base; > + typedef typename _Base::_Tp_alloc_type _Alloc_traits; > + > +public: > + typedef _Tp value_type; > + typedef typename _Base::pointer pointer; > + typedef typename _Alloc_traits::const_pointer const_pointer; > + typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator; > + typedef __gnu_cxx::__normal_iterator<const_pointer, vector> const_iterator; > + iterator begin(); > + iterator insert(const_iterator, const value_type &); > + struct _Temporary_value {}; > + template <typename _Arg> void _M_insert_aux(iterator, _Arg &&); > +}; > +template <typename _Tp, typename _Alloc> > +typename vector<_Tp, _Alloc>::iterator > +vector<_Tp, _Alloc>::insert(const_iterator, const value_type &) { > + auto __pos = begin(); > + _Temporary_value __x_copy; > + _M_insert_aux(__pos, __x_copy); > +} > +template <typename _Tp, typename _Alloc> > +template <typename _Arg> > +void vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, _Arg &&) { > + move_backward(__position.base(), this->_M_impl._M_finish, > + this->_M_impl._M_finish); > +} > +namespace internals { > +struct distributing { > + distributing &operator=(const distributing &); > + int global_row; > + *constraints; /* { dg-warning "with no type" "" } */ > +}; > +distributing &distributing::operator=(const distributing &in) { > + global_row = in.global_row; > + return; /* { dg-warning "return-statement with no value" "" } */ > +} > +insert_index(vector<distributing> my_indices) { /* { dg-warning "with no > type" "" } */ > + typedef vector<distributing>::iterator index_iterator; > + index_iterator pos; > + distributing row_value; > + my_indices.insert(pos, row_value); > +} > +} // namespace internals > +} // namespace std > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp > b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp > index 877cc55bb88..e128b1733e8 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp > +++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp > @@ -47,7 +47,7 @@ dg-runtest [lsort [glob -nocomplain > $srcdir/$subdir/xandesvector/*.\[cS\]]] \ > "" $CFLAGS > gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vsetvl/*.\[cS\]]] \ > "" $CFLAGS > -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[cS\]]] \ > +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[cCS\]]] \ > "-O3 -ftree-vectorize" $CFLAGS
This will fail if you only have `--enable-languages=c` (yes this is still supported for cross compiling). Maybe it is time to have g++.target/riscv/rvv/rvv.exp. Thanks, Andrew Pinski > dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/vls/*.\[cS\]]] \ > "-O3 -ftree-vectorize -mrvv-vector-bits=scalable" $CFLAGS > diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc > index 53923c07e18..f9dd88ed824 100644 > --- a/gcc/tree-vect-loop.cc > +++ b/gcc/tree-vect-loop.cc > @@ -2682,6 +2682,7 @@ again: > = saved_can_use_partial_vectors_p; > LOOP_VINFO_MUST_USE_PARTIAL_VECTORS_P (loop_vinfo) = false; > LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo) = false; > + LOOP_VINFO_USING_SELECT_VL_P (loop_vinfo) = false; > if (loop_vinfo->scan_map) > loop_vinfo->scan_map->empty (); > > -- > 2.51.1 >
