2019-08-30 Jakub Jelinek Backported from mainline 2019-03-13 Jakub Jelinek 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 (revision 270725) +++ gcc/omp-simd-clone.c (revision 270726) @@ -868,6 +868,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)) @@ -884,7 +896,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; } @@ -985,6 +1008,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 (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 (nonexistent) +++ gcc/testsuite/c-c++-common/gomp/pr88588.c (revision 270726) @@ -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; + } +}