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

Reply via email to