Avoid ICE for nested inductions (PR 83914)
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 19 Jan 2018 11:57:34 +0000 (11:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 19 Jan 2018 11:57:34 +0000 (11:57 +0000)
This testcase ICEd because we converted the initial value of an
induction to the vector element type even for nested inductions.
This isn't necessary because the initial expression is vectorised
normally, and it meant that init_expr was no longer the original
statement operand by the time we called vect_get_vec_def_for_operand.

Also, adding the conversion code here made the existing SLP conversion
redundant.

2018-01-19  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
PR tree-optimization/83914
* tree-vect-loop.c (vectorizable_induction): Don't convert
init_expr or apply the peeling adjustment for inductions
that are nested within the vectorized loop.

gcc/testsuite/
PR tree-optimization/83914
* gcc.dg/vect/pr83914.c: New test.

From-SVN: r256884

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr83914.c [new file with mode: 0644]
gcc/tree-vect-loop.c

index 5feefb2dda8adad19fef52bea9796fb2f29f7dc7..a86ea914ca554ce7589e93fe2cc2b43ab3115b57 100644 (file)
@@ -1,3 +1,10 @@
+2018-01-19  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR tree-optimization/83914
+       * tree-vect-loop.c (vectorizable_induction): Don't convert
+       init_expr or apply the peeling adjustment for inductions
+       that are nested within the vectorized loop.
+
 2018-01-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/thumb2.md (*thumb2_negsi2_short): Use RSB mnemonic
index ef525655391d712e630b2df49308bc3408753b8d..44080e0b54af607f190658b631fb57800ecf7f5d 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-19  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR tree-optimization/83914
+       * gcc.dg/vect/pr83914.c: New test.
+
 2018-01-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * gcc.target/arm/negdi-1.c: Remove bogus assembler scan for negs.
diff --git a/gcc/testsuite/gcc.dg/vect/pr83914.c b/gcc/testsuite/gcc.dg/vect/pr83914.c
new file mode 100644 (file)
index 0000000..0bef798
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3" } */
+
+struct s { struct s *ptrs[16]; } *a, *b;
+int c;
+void
+foo (int n)
+{
+  for (; n; a = b, n--)
+    {
+      b = a + 1;
+      for (c = 8; c; c--)
+       a->ptrs[c] = b;
+    }
+}
index 79b818608dff1633b9feec654174b30e163b270c..8b2ecf84e3f652e2a31cbd5bcbb0c34d59f0e6b8 100644 (file)
@@ -7678,28 +7678,33 @@ vectorizable_induction (gimple *phi,
   init_expr = PHI_ARG_DEF_FROM_EDGE (phi,
                                     loop_preheader_edge (iv_loop));
 
-  /* Convert the initial value and step to the desired type.  */
   stmts = NULL;
-  init_expr = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr);
-  step_expr = gimple_convert (&stmts, TREE_TYPE (vectype), step_expr);
-
-  /* If we are using the loop mask to "peel" for alignment then we need
-     to adjust the start value here.  */
-  tree skip_niters = LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo);
-  if (skip_niters != NULL_TREE)
+  if (!nested_in_vect_loop)
     {
-      if (FLOAT_TYPE_P (vectype))
-       skip_niters = gimple_build (&stmts, FLOAT_EXPR, TREE_TYPE (vectype),
-                                   skip_niters);
-      else
-       skip_niters = gimple_convert (&stmts, TREE_TYPE (vectype),
-                                     skip_niters);
-      tree skip_step = gimple_build (&stmts, MULT_EXPR, TREE_TYPE (vectype),
-                                    skip_niters, step_expr);
-      init_expr = gimple_build (&stmts, MINUS_EXPR, TREE_TYPE (vectype),
-                               init_expr, skip_step);
+      /* Convert the initial value to the desired type.  */
+      tree new_type = TREE_TYPE (vectype);
+      init_expr = gimple_convert (&stmts, new_type, init_expr);
+
+      /* If we are using the loop mask to "peel" for alignment then we need
+        to adjust the start value here.  */
+      tree skip_niters = LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo);
+      if (skip_niters != NULL_TREE)
+       {
+         if (FLOAT_TYPE_P (vectype))
+           skip_niters = gimple_build (&stmts, FLOAT_EXPR, new_type,
+                                       skip_niters);
+         else
+           skip_niters = gimple_convert (&stmts, new_type, skip_niters);
+         tree skip_step = gimple_build (&stmts, MULT_EXPR, new_type,
+                                        skip_niters, step_expr);
+         init_expr = gimple_build (&stmts, MINUS_EXPR, new_type,
+                                   init_expr, skip_step);
+       }
     }
 
+  /* Convert the step to the desired type.  */
+  step_expr = gimple_convert (&stmts, TREE_TYPE (vectype), step_expr);
+
   if (stmts)
     {
       new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
@@ -7718,15 +7723,6 @@ vectorizable_induction (gimple *phi,
       /* Enforced above.  */
       unsigned int const_nunits = nunits.to_constant ();
 
-      /* Convert the init to the desired type.  */
-      stmts = NULL;
-      init_expr = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr);
-      if (stmts)
-       {
-         new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
-         gcc_assert (!new_bb);
-       }
-
       /* Generate [VF*S, VF*S, ... ].  */
       if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr)))
        {