Hi!

For normal stmts, preparation statements are inserted before the stmt, so if we 
need multiple,
they are in the correct order, but for PHIs we emit them after labels in the 
entry successor
bb, and we used to emit them in the reverse order that way.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk (so far).

2020-05-14  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/95108
        * omp-simd-clone.c (struct modify_stmt_info): Add after_stmt member.
        (ipa_simd_modify_stmt_ops): For PHIs, only add before first stmt in
        entry block if info->after_stmt is NULL, otherwise add after that stmt
        and update it after adding each stmt.
        (ipa_simd_modify_function_body): Initialize info.after_stmt.

        * gcc.dg/gomp/pr95108.c: New test.

--- gcc/omp-simd-clone.c.jj     2020-05-13 19:10:38.000000000 +0200
+++ gcc/omp-simd-clone.c        2020-05-13 20:41:06.554959692 +0200
@@ -821,6 +821,7 @@ simd_clone_init_simd_arrays (struct cgra
 struct modify_stmt_info {
   ipa_param_body_adjustments *adjustments;
   gimple *stmt;
+  gimple *after_stmt;
   /* True if the parent statement was modified by
      ipa_simd_modify_stmt_ops.  */
   bool modified;
@@ -912,7 +913,10 @@ ipa_simd_modify_stmt_ops (tree *tp, int
       gimple_stmt_iterator gsi;
       if (gimple_code (info->stmt) == GIMPLE_PHI)
        {
-         gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+         if (info->after_stmt)
+           gsi = gsi_for_stmt (info->after_stmt);
+         else
+           gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN 
(cfun)));
          /* Cache SSA_NAME for next time.  */
          if (pbr
              && TREE_CODE (*orig_tp) == ADDR_EXPR
@@ -924,7 +928,12 @@ ipa_simd_modify_stmt_ops (tree *tp, int
        }
       else
        gsi = gsi_for_stmt (info->stmt);
-      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+      if (info->after_stmt)
+       gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
+      else
+       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+      if (gimple_code (info->stmt) == GIMPLE_PHI)
+       info->after_stmt = stmt;
       *orig_tp = repl;
     }
   else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
@@ -1015,6 +1024,7 @@ ipa_simd_modify_function_body (struct cg
          gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
          int i, n = gimple_phi_num_args (phi);
          info.stmt = phi;
+         info.after_stmt = NULL;
          struct walk_stmt_info wi;
          memset (&wi, 0, sizeof (wi));
          info.modified = false;
@@ -1040,6 +1050,7 @@ ipa_simd_modify_function_body (struct cg
        {
          gimple *stmt = gsi_stmt (gsi);
          info.stmt = stmt;
+         info.after_stmt = NULL;
          struct walk_stmt_info wi;
 
          memset (&wi, 0, sizeof (wi));
--- gcc/testsuite/gcc.dg/gomp/pr95108.c.jj      2020-05-13 20:48:50.838004215 
+0200
+++ gcc/testsuite/gcc.dg/gomp/pr95108.c 2020-05-13 20:51:08.492942286 +0200
@@ -0,0 +1,18 @@
+/* PR middle-end/95108 */
+/* { dg-do compile { target vect_simd_clones } } */
+/* { dg-options "-O2 -fopenmp-simd -w" } */
+
+int *v;
+
+#pragma omp declare simd
+void
+foo (int x)
+{
+  int *a = &x + 1;
+
+  for (;;)
+    {
+      *v = *a;
+      a = v;
+    }
+}

        Jakub

Reply via email to