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