Hi All,

We can't support nonlinear inductions other than neg when vectorizing
early breaks and iteration count is known.

For early break we currently require a peeled epilog but in these cases
we can't compute the remaining values.

Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
tested on cross cc1 for amdgcn-amdhsa and issue fixed.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

        PR middle-end/113163
        * tree-vect-loop-manip.cc (vect_can_peel_nonlinear_iv_p):

gcc/testsuite/ChangeLog:

        PR middle-end/113163
        * gcc.target/gcn/pr113163.c: New test.

--- inline copy of patch -- 
diff --git a/gcc/testsuite/gcc.target/gcn/pr113163.c 
b/gcc/testsuite/gcc.target/gcn/pr113163.c
new file mode 100644
index 
0000000000000000000000000000000000000000..99b0fdbaf3a3152ca008b5109abf6e80d8cb3d6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/pr113163.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize" } */ 
+
+struct _reent { union { struct { char _l64a_buf[8]; } _reent; } _new; };
+static const char R64_ARRAY[] = 
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+char *
+_l64a_r (struct _reent *rptr,
+     long value)
+{
+  char *ptr;
+  char *result;
+  int i, index;
+  unsigned long tmp = (unsigned long)value & 0xffffffff;
+  result = 
+          ((
+          rptr
+          )->_new._reent._l64a_buf)
+                               ;
+  ptr = result;
+  for (i = 0; i < 6; ++i)
+    {
+      if (tmp == 0)
+ {
+   *ptr = '\0';
+   break;
+ }
+      *ptr++ = R64_ARRAY[index];
+      tmp >>= 6;
+    }
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 
3810983a80c8b989be9fd9a9993642069fd39b99..f1bf43b3731868e7b053c186302fbeaf515be8cf
 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -2075,6 +2075,22 @@ vect_can_peel_nonlinear_iv_p (loop_vec_info loop_vinfo,
       return false;
     }
 
+  /* We can't support partial vectors and early breaks with an induction
+     type other than add or neg since we require the epilog and can't
+     perform the peeling.  PR113163.  */
+  if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
+      && LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant ()
+      && LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
+      && induction_type != vect_step_op_neg)
+    {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "Peeling for epilogue is not supported"
+                        " for nonlinear induction except neg"
+                        " when iteration count is known and early breaks.\n");
+      return false;
+    }
+
   return true;
 }
 




-- 
diff --git a/gcc/testsuite/gcc.target/gcn/pr113163.c 
b/gcc/testsuite/gcc.target/gcn/pr113163.c
new file mode 100644
index 
0000000000000000000000000000000000000000..99b0fdbaf3a3152ca008b5109abf6e80d8cb3d6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/gcn/pr113163.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize" } */ 
+
+struct _reent { union { struct { char _l64a_buf[8]; } _reent; } _new; };
+static const char R64_ARRAY[] = 
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+char *
+_l64a_r (struct _reent *rptr,
+     long value)
+{
+  char *ptr;
+  char *result;
+  int i, index;
+  unsigned long tmp = (unsigned long)value & 0xffffffff;
+  result = 
+          ((
+          rptr
+          )->_new._reent._l64a_buf)
+                               ;
+  ptr = result;
+  for (i = 0; i < 6; ++i)
+    {
+      if (tmp == 0)
+ {
+   *ptr = '\0';
+   break;
+ }
+      *ptr++ = R64_ARRAY[index];
+      tmp >>= 6;
+    }
+}
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 
3810983a80c8b989be9fd9a9993642069fd39b99..f1bf43b3731868e7b053c186302fbeaf515be8cf
 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -2075,6 +2075,22 @@ vect_can_peel_nonlinear_iv_p (loop_vec_info loop_vinfo,
       return false;
     }
 
+  /* We can't support partial vectors and early breaks with an induction
+     type other than add or neg since we require the epilog and can't
+     perform the peeling.  PR113163.  */
+  if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo)
+      && LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant ()
+      && LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
+      && induction_type != vect_step_op_neg)
+    {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "Peeling for epilogue is not supported"
+                        " for nonlinear induction except neg"
+                        " when iteration count is known and early breaks.\n");
+      return false;
+    }
+
   return true;
 }
 



Reply via email to