re PR tree-optimization/83359 (ICE in expand_LOOP_DIST_ALIAS, at internal-fn.c:2362)
authorJakub Jelinek <jakub@redhat.com>
Tue, 12 Dec 2017 09:21:35 +0000 (10:21 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 12 Dec 2017 09:21:35 +0000 (10:21 +0100)
PR tree-optimization/83359
* tree-cfg.h (fold_loop_internal_call): Declare.
* tree-vectorizer.c (fold_loop_internal_call): Moved to ...
* tree-cfg.c (fold_loop_internal_call): ... here.  No longer static.
(find_loop_dist_alias): New function.
(move_sese_region_to_fn): If any dloop->orig_loop_num value is
updated, also adjust any corresponding LOOP_DIST_ALIAS internal
calls.

* gcc.dg/graphite/pr83359.c: New test.

From-SVN: r255575

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/graphite/pr83359.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-cfg.h
gcc/tree-vectorizer.c

index 1e26d7b..8c24c0e 100644 (file)
@@ -1,5 +1,14 @@
 2017-12-12  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/83359
+       * tree-cfg.h (fold_loop_internal_call): Declare.
+       * tree-vectorizer.c (fold_loop_internal_call): Moved to ...
+       * tree-cfg.c (fold_loop_internal_call): ... here.  No longer static.
+       (find_loop_dist_alias): New function.
+       (move_sese_region_to_fn): If any dloop->orig_loop_num value is
+       updated, also adjust any corresponding LOOP_DIST_ALIAS internal
+       calls.
+
        PR tree-optimization/80631
        * tree-vect-loop.c (get_initial_def_for_reduction): Fix comment typo.
        (vect_create_epilog_for_reduction): Add INDUC_VAL and INDUC_CODE
index fcb4c6d..811ec8d 100644 (file)
@@ -1,5 +1,8 @@
 2017-12-12  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/83359
+       * gcc.dg/graphite/pr83359.c: New test.
+
        PR tree-optimization/80631
        * gcc.dg/vect/pr80631-1.c: New test.
        * gcc.dg/vect/pr80631-2.c: New test.
diff --git a/gcc/testsuite/gcc.dg/graphite/pr83359.c b/gcc/testsuite/gcc.dg/graphite/pr83359.c
new file mode 100644 (file)
index 0000000..9117118
--- /dev/null
@@ -0,0 +1,40 @@
+/* PR tree-optimization/83359 */
+/* { dg-do compile { target pthread } } */
+/* { dg-options "-O3 -floop-parallelize-all -ftree-parallelize-loops=2" } */
+
+int a, b, c;
+
+void
+foo (int x, int y)
+{
+  int *d = &a;
+  int *e = &x;
+
+  for (a = 0; a < 1; ++a)
+    d = &x;
+
+  while (b < 10)
+    {
+      for (b = 0; b < 1; ++b)
+        if (x == 0)
+          while (x < 1)
+            ++x;
+        else
+          while (x < 1)
+            {
+              d = &y;
+              ++x;
+            }
+      ++b;
+    }
+
+  for (;;)
+    for (c = 0; c < 2; ++c)
+      {
+        if (*d != 0)
+          a = *e;
+
+        e = &b;
+        y = 0;
+      }
+}
index b00a291..9a4e3e2 100644 (file)
@@ -7375,6 +7375,47 @@ gather_ssa_name_hash_map_from (tree const &from, tree const &, void *data)
   return true;
 }
 
+/* Return LOOP_DIST_ALIAS call if present in BB.  */
+
+static gimple *
+find_loop_dist_alias (basic_block bb)
+{
+  gimple *g = last_stmt (bb);
+  if (g == NULL || gimple_code (g) != GIMPLE_COND)
+    return NULL;
+
+  gimple_stmt_iterator gsi = gsi_for_stmt (g);
+  gsi_prev (&gsi);
+  if (gsi_end_p (gsi))
+    return NULL;
+
+  g = gsi_stmt (gsi);
+  if (gimple_call_internal_p (g, IFN_LOOP_DIST_ALIAS))
+    return g;
+  return NULL;
+}
+
+/* Fold loop internal call G like IFN_LOOP_VECTORIZED/IFN_LOOP_DIST_ALIAS
+   to VALUE and update any immediate uses of it's LHS.  */
+
+void
+fold_loop_internal_call (gimple *g, tree value)
+{
+  tree lhs = gimple_call_lhs (g);
+  use_operand_p use_p;
+  imm_use_iterator iter;
+  gimple *use_stmt;
+  gimple_stmt_iterator gsi = gsi_for_stmt (g);
+
+  update_call_from_tree (&gsi, value);
+  FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
+    {
+      FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+       SET_USE (use_p, value);
+      update_stmt (use_stmt);
+    }
+}
+
 /* Move a single-entry, single-exit region delimited by ENTRY_BB and
    EXIT_BB to function DEST_CFUN.  The whole region is replaced by a
    single basic block in the original CFG and the new basic block is
@@ -7548,7 +7589,6 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
          }
     }
 
-
   /* Adjust the number of blocks in the tree root of the outlined part.  */
   get_loop (dest_cfun, 0)->num_nodes = bbs.length () + 2;
 
@@ -7559,19 +7599,77 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
   /* Fix up orig_loop_num.  If the block referenced in it has been moved
      to dest_cfun, update orig_loop_num field, otherwise clear it.  */
   struct loop *dloop;
+  signed char *moved_orig_loop_num = NULL;
   FOR_EACH_LOOP_FN (dest_cfun, dloop, 0)
     if (dloop->orig_loop_num)
       {
+       if (moved_orig_loop_num == NULL)
+         moved_orig_loop_num
+           = XCNEWVEC (signed char, vec_safe_length (larray));
        if ((*larray)[dloop->orig_loop_num] != NULL
            && get_loop (saved_cfun, dloop->orig_loop_num) == NULL)
-         dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num;
+         {
+           if (moved_orig_loop_num[dloop->orig_loop_num] >= 0
+               && moved_orig_loop_num[dloop->orig_loop_num] < 2)
+             moved_orig_loop_num[dloop->orig_loop_num]++;
+           dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num;
+         }
        else
-         dloop->orig_loop_num = 0;
+         {
+           moved_orig_loop_num[dloop->orig_loop_num] = -1;
+           dloop->orig_loop_num = 0;
+         }
       }
-  ggc_free (larray);
-
   pop_cfun ();
 
+  if (moved_orig_loop_num)
+    {
+      FOR_EACH_VEC_ELT (bbs, i, bb)
+       {
+         gimple *g = find_loop_dist_alias (bb);
+         if (g == NULL)
+           continue;
+
+         int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0));
+         gcc_assert (orig_loop_num
+                     && (unsigned) orig_loop_num < vec_safe_length (larray));
+         if (moved_orig_loop_num[orig_loop_num] == 2)
+           {
+             /* If we have moved both loops with this orig_loop_num into
+                dest_cfun and the LOOP_DIST_ALIAS call is being moved there
+                too, update the first argument.  */
+             gcc_assert ((*larray)[dloop->orig_loop_num] != NULL
+                         && (get_loop (saved_cfun, dloop->orig_loop_num)
+                             == NULL));
+             tree t = build_int_cst (integer_type_node,
+                                     (*larray)[dloop->orig_loop_num]->num);
+             gimple_call_set_arg (g, 0, t);
+             update_stmt (g);
+             /* Make sure the following loop will not update it.  */
+             moved_orig_loop_num[orig_loop_num] = 0;
+           }
+         else
+           /* Otherwise at least one of the loops stayed in saved_cfun.
+              Remove the LOOP_DIST_ALIAS call.  */
+           fold_loop_internal_call (g, gimple_call_arg (g, 1));
+       }
+      FOR_EACH_BB_FN (bb, saved_cfun)
+       {
+         gimple *g = find_loop_dist_alias (bb);
+         if (g == NULL)
+           continue;
+         int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0));
+         gcc_assert (orig_loop_num
+                     && (unsigned) orig_loop_num < vec_safe_length (larray));
+         if (moved_orig_loop_num[orig_loop_num])
+           /* LOOP_DIST_ALIAS call remained in saved_cfun, if at least one
+              of the corresponding loops was moved, remove it.  */
+           fold_loop_internal_call (g, gimple_call_arg (g, 1));
+       }
+      XDELETEVEC (moved_orig_loop_num);
+    }
+  ggc_free (larray);
+
   /* Move blocks from BBS into DEST_CFUN.  */
   gcc_assert (bbs.length () >= 2);
   after = dest_cfun->cfg->x_entry_block_ptr;
index 7a08cb0..12deaa3 100644 (file)
@@ -77,6 +77,7 @@ extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
                                          vec<basic_block> *bbs_p);
 extern void verify_sese (basic_block, basic_block, vec<basic_block> *);
 extern bool gather_ssa_name_hash_map_from (tree const &, tree const &, void *);
+extern void fold_loop_internal_call (gimple *, tree);
 extern basic_block move_sese_region_to_fn (struct function *, basic_block,
                                           basic_block, tree);
 extern void dump_function_to_file (tree, FILE *, dump_flags_t);
index feddfa2..a46d2a3 100644 (file)
@@ -464,27 +464,6 @@ vect_loop_vectorized_call (struct loop *loop)
   return NULL;
 }
 
-/* Fold loop internal call G like IFN_LOOP_VECTORIZED/IFN_LOOP_DIST_ALIAS
-   to VALUE and update any immediate uses of it's LHS.  */
-
-static void
-fold_loop_internal_call (gimple *g, tree value)
-{
-  tree lhs = gimple_call_lhs (g);
-  use_operand_p use_p;
-  imm_use_iterator iter;
-  gimple *use_stmt;
-  gimple_stmt_iterator gsi = gsi_for_stmt (g);
-
-  update_call_from_tree (&gsi, value);
-  FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
-    {
-      FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
-       SET_USE (use_p, value);
-      update_stmt (use_stmt);
-    }
-}
-
 /* If LOOP has been versioned during loop distribution, return the gurading
    internal call.  */