In the given test case, the loop is split into vectorised and non
vectorised
versions due to peeling. At the end of the loop the IVs are incremented to
their latest value. This is achieved by taking the base of the loop (g_21)
and
adding the iterations (240) multiplied by the step (_6):

  <bb 15>:
  # _106 = PHI <_6(12)>
  _84 = _106 * 240;
  _85 = (char) _84;
  tmp.19_83 = g_21(D) + _85;

However, the step (_6) varies within the loop and therefore the
calculation is
incorrect.

This patch fixes the error by disallowing vectorization if the step of the
IV
is not an invariant within the loop.

Also added debug comment for when the optimisation fails due to chrec.

Tested on x86.

Ok to commit?

Alan.


gcc/
        PR tree-optimization/71818
        * tree-vect-loop-manip.c (vect_can_advance_ivs_p): Don't advance IVs
        with non invariant evolutions

testsuite/
        PR tree-optimization/71818
        * gcc.dg/vect/pr71818.c: New





diff --git a/gcc/testsuite/gcc.dg/vect/pr71818.c
b/gcc/testsuite/gcc.dg/vect/pr71818.c
new file mode 100644
index 
0000000000000000000000000000000000000000..2946551f8bb8c552565c2e79b16359ca3
9d13ed6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr71818.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+
+char a;
+short b;
+int c, d;
+void fn1() {
+  char e = 75, g;
+  unsigned char *f = &e;
+  a = 21;
+  for (; a <= 48; a++) {
+    for (; e <= 6;)
+      ;
+    g -= e -= b || g <= c;
+  }
+  d = *f;
+}
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 
819abcda81a25c4ed25749c29b357110fca647d2..4d68f7143e1117085aae8d2168ed1425e
7e6aa08 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
+#include "tree-ssa-loop-ivopts.h"

 /*************************************************************************
   Simple Loop Peeling Utilities
@@ -1592,10 +1593,26 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
         }

       /* FORNOW: We do not transform initial conditions of IVs
+        which evolution functions are not invariants in the loop.  */
+
+      if (!expr_invariant_in_loop_p (loop, evolution_part))
+       {
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "evolution not invariant in loop.\n");
+         return false;
+       }
+
+      /* FORNOW: We do not transform initial conditions of IVs
         which evolution functions are a polynomial of degree >= 2.  */

       if (tree_is_chrec (evolution_part))
-       return false;
+       {
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "evolution is chrec.\n");
+         return false;
+       }
     }

   return true;





Reply via email to