Hi!

As the testcase shows (not really useful example of what simd functions
should be used for though), I forgot to adjust PHI arguments.  They can
contain &parm and if the parm is to be passed as vector, we want to replace
it with &array[iter_N].  That is not a valid gimple invariant though,
so we need to emit it in some other bb.  I chose to just emit it on the
first bb in the function, which is going to become the body of the new loop
that is supposed to be vectorized.  The code abuses otherwise unused
cand->alias_ptr_type (used just for IPA SRA, not in this case) for caching
a SSA_NAME containing the address, so that if we have many PHI nodes with
&parm, we don't create a SSA_NAME for each of them and hope some SCCVN will
clean it up.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2019-03-13  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/88588
        * omp-simd-clone.c (ipa_simd_modify_stmt_ops): Handle PHI args.
        (ipa_simd_modify_function_body): Handle PHIs.

        * c-c++-common/gomp/pr88588.c: New test.

--- gcc/omp-simd-clone.c.jj     2019-02-08 16:02:42.096813415 +0100
+++ gcc/omp-simd-clone.c        2019-03-12 20:56:25.949386379 +0100
@@ -866,6 +866,18 @@ ipa_simd_modify_stmt_ops (tree *tp, int
 
   if (tp != orig_tp)
     {
+      if (gimple_code (info->stmt) == GIMPLE_PHI
+         && cand
+         && TREE_CODE (*orig_tp) == ADDR_EXPR
+         && TREE_CODE (TREE_OPERAND (*orig_tp, 0)) == PARM_DECL
+         && cand->alias_ptr_type)
+       {
+         gcc_assert (TREE_CODE (cand->alias_ptr_type) == SSA_NAME);
+         *orig_tp = cand->alias_ptr_type;
+         info->modified = true;
+         return NULL_TREE;
+       }
+
       repl = build_fold_addr_expr (repl);
       gimple *stmt;
       if (is_gimple_debug (info->stmt))
@@ -882,7 +894,18 @@ ipa_simd_modify_stmt_ops (tree *tp, int
          stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl)), repl);
          repl = gimple_assign_lhs (stmt);
        }
-      gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
+      gimple_stmt_iterator gsi;
+      if (gimple_code (info->stmt) == GIMPLE_PHI)
+       {
+         gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+         /* Cache SSA_NAME for next time.  */
+         if (cand
+             && TREE_CODE (*orig_tp) == ADDR_EXPR
+             && TREE_CODE (TREE_OPERAND (*orig_tp, 0)) == PARM_DECL)
+           cand->alias_ptr_type = repl;
+       }
+      else
+       gsi = gsi_for_stmt (info->stmt);
       gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
       *orig_tp = repl;
     }
@@ -983,6 +1006,31 @@ ipa_simd_modify_function_body (struct cg
     {
       gimple_stmt_iterator gsi;
 
+      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+       {
+         gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
+         int i, n = gimple_phi_num_args (phi);
+         info.stmt = phi;
+         struct walk_stmt_info wi;
+         memset (&wi, 0, sizeof (wi));
+         info.modified = false;
+         wi.info = &info;
+         for (i = 0; i < n; ++i)
+           {
+             int walk_subtrees = 1;
+             tree arg = gimple_phi_arg_def (phi, i);
+             tree op = arg;
+             ipa_simd_modify_stmt_ops (&op, &walk_subtrees, &wi);
+             if (op != arg)
+               {
+                 SET_PHI_ARG_DEF (phi, i, op);
+                 gcc_assert (TREE_CODE (op) == SSA_NAME);
+                 if (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
+                   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op) = 1;
+               }
+           }
+       }
+
       gsi = gsi_start_bb (bb);
       while (!gsi_end_p (gsi))
        {
--- gcc/testsuite/c-c++-common/gomp/pr88588.c.jj        2019-03-12 
21:00:11.886712729 +0100
+++ gcc/testsuite/c-c++-common/gomp/pr88588.c   2019-03-12 21:00:51.799063771 
+0100
@@ -0,0 +1,18 @@
+/* PR middle-end/88588 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -O1" } */
+
+int *v;
+
+#pragma omp declare simd
+void
+foo (int x)
+{
+  int *a = &x;
+
+  for (;;)
+    {
+      *v = *a;
+      a = v;
+    }
+}

        Jakub

Reply via email to