Commit 4ce71579 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/78025 (ICE in simd_clone_adjust, at omp-simd-clone.c:1126)

	PR middle-end/78025
	* omp-simd-clone.c (simd_clone_adjust): Handle noreturn declare simd
	functions.

	* g++.dg/gomp/declare-simd-7.C: New test.

From-SVN: r241628
parent 015c7760
2016-10-27 Jakub Jelinek <jakub@redhat.com>
PR middle-end/78025
* omp-simd-clone.c (simd_clone_adjust): Handle noreturn declare simd
functions.
2016-10-27 Aldy Hernandez <aldyh@redhat.com> 2016-10-27 Aldy Hernandez <aldyh@redhat.com>
* builtins.c (expand_builtin_nonlocal_goto): Avoid evaluating * builtins.c (expand_builtin_nonlocal_goto): Avoid evaluating
...@@ -1107,7 +1107,7 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1107,7 +1107,7 @@ simd_clone_adjust (struct cgraph_node *node)
return values accordingly. */ return values accordingly. */
tree iter = create_tmp_var (unsigned_type_node, "iter"); tree iter = create_tmp_var (unsigned_type_node, "iter");
tree iter1 = make_ssa_name (iter); tree iter1 = make_ssa_name (iter);
tree iter2 = make_ssa_name (iter); tree iter2 = NULL_TREE;
ipa_simd_modify_function_body (node, adjustments, retval, iter1); ipa_simd_modify_function_body (node, adjustments, retval, iter1);
adjustments.release (); adjustments.release ();
...@@ -1121,39 +1121,57 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1121,39 +1121,57 @@ simd_clone_adjust (struct cgraph_node *node)
pop_gimplify_context (NULL); pop_gimplify_context (NULL);
gimple *g;
basic_block incr_bb = NULL;
struct loop *loop = NULL;
/* Create a new BB right before the original exit BB, to hold the /* Create a new BB right before the original exit BB, to hold the
iteration increment and the condition/branch. */ iteration increment and the condition/branch. */
basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src; if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
basic_block incr_bb = create_empty_bb (orig_exit); {
add_bb_to_loop (incr_bb, body_bb->loop_father); basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
/* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty incr_bb = create_empty_bb (orig_exit);
flag. Set it now to be a FALLTHRU_EDGE. */ add_bb_to_loop (incr_bb, body_bb->loop_father);
gcc_assert (EDGE_COUNT (orig_exit->succs) == 1); /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU; flag. Set it now to be a FALLTHRU_EDGE. */
for (unsigned i = 0; gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i) EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
for (unsigned i = 0;
i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
{
edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
redirect_edge_succ (e, incr_bb);
}
}
else if (node->simdclone->inbranch)
{
incr_bb = create_empty_bb (entry_bb);
add_bb_to_loop (incr_bb, body_bb->loop_father);
}
if (incr_bb)
{ {
edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i); edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
redirect_edge_succ (e, incr_bb); e->probability = REG_BR_PROB_BASE;
gsi = gsi_last_bb (incr_bb);
iter2 = make_ssa_name (iter);
g = gimple_build_assign (iter2, PLUS_EXPR, iter1,
build_int_cst (unsigned_type_node, 1));
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
/* Mostly annotate the loop for the vectorizer (the rest is done
below). */
loop = alloc_loop ();
cfun->has_force_vectorize_loops = true;
loop->safelen = node->simdclone->simdlen;
loop->force_vectorize = true;
loop->header = body_bb;
} }
edge e = make_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
e->probability = REG_BR_PROB_BASE;
gsi = gsi_last_bb (incr_bb);
gimple *g = gimple_build_assign (iter2, PLUS_EXPR, iter1,
build_int_cst (unsigned_type_node, 1));
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
/* Mostly annotate the loop for the vectorizer (the rest is done below). */
struct loop *loop = alloc_loop ();
cfun->has_force_vectorize_loops = true;
loop->safelen = node->simdclone->simdlen;
loop->force_vectorize = true;
loop->header = body_bb;
/* Branch around the body if the mask applies. */ /* Branch around the body if the mask applies. */
if (node->simdclone->inbranch) if (node->simdclone->inbranch)
{ {
gimple_stmt_iterator gsi = gsi_last_bb (loop->header); gsi = gsi_last_bb (loop->header);
tree mask_array tree mask_array
= node->simdclone->args[node->simdclone->nargs - 1].simd_array; = node->simdclone->args[node->simdclone->nargs - 1].simd_array;
tree mask; tree mask;
...@@ -1227,50 +1245,59 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1227,50 +1245,59 @@ simd_clone_adjust (struct cgraph_node *node)
FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE; FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
} }
basic_block latch_bb = NULL;
basic_block new_exit_bb = NULL;
/* Generate the condition. */ /* Generate the condition. */
g = gimple_build_cond (LT_EXPR, if (incr_bb)
iter2, {
build_int_cst (unsigned_type_node, gsi = gsi_last_bb (incr_bb);
node->simdclone->simdlen), g = gimple_build_cond (LT_EXPR, iter2,
NULL, NULL); build_int_cst (unsigned_type_node,
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING); node->simdclone->simdlen),
e = split_block (incr_bb, gsi_stmt (gsi)); NULL, NULL);
basic_block latch_bb = e->dest; gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
basic_block new_exit_bb; edge e = split_block (incr_bb, gsi_stmt (gsi));
new_exit_bb = split_block_after_labels (latch_bb)->dest; latch_bb = e->dest;
loop->latch = latch_bb; new_exit_bb = split_block_after_labels (latch_bb)->dest;
loop->latch = latch_bb;
redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);
make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
/* The successor of incr_bb is already pointing to latch_bb; just make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);
change the flags. /* The successor of incr_bb is already pointing to latch_bb; just
make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE); */ change the flags.
FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE; make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE); */
FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
}
gphi *phi = create_phi_node (iter1, body_bb); gphi *phi = create_phi_node (iter1, body_bb);
edge preheader_edge = find_edge (entry_bb, body_bb); edge preheader_edge = find_edge (entry_bb, body_bb);
edge latch_edge = single_succ_edge (latch_bb); edge latch_edge = NULL;
add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge, add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
UNKNOWN_LOCATION); UNKNOWN_LOCATION);
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION); if (incr_bb)
/* Generate the new return. */
gsi = gsi_last_bb (new_exit_bb);
if (retval
&& TREE_CODE (retval) == VIEW_CONVERT_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
retval = TREE_OPERAND (retval, 0);
else if (retval)
{ {
retval = build1 (VIEW_CONVERT_EXPR, latch_edge = single_succ_edge (latch_bb);
TREE_TYPE (TREE_TYPE (node->decl)), add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
retval);
retval = force_gimple_operand_gsi (&gsi, retval, true, NULL, /* Generate the new return. */
false, GSI_CONTINUE_LINKING); gsi = gsi_last_bb (new_exit_bb);
if (retval
&& TREE_CODE (retval) == VIEW_CONVERT_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
retval = TREE_OPERAND (retval, 0);
else if (retval)
{
retval = build1 (VIEW_CONVERT_EXPR,
TREE_TYPE (TREE_TYPE (node->decl)),
retval);
retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
false, GSI_CONTINUE_LINKING);
}
g = gimple_build_return (retval);
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
} }
g = gimple_build_return (retval);
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
/* Handle aligned clauses by replacing default defs of the aligned /* Handle aligned clauses by replacing default defs of the aligned
uniform args with __builtin_assume_aligned (arg_N(D), alignment) uniform args with __builtin_assume_aligned (arg_N(D), alignment)
...@@ -1386,7 +1413,8 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1386,7 +1413,8 @@ simd_clone_adjust (struct cgraph_node *node)
{ {
def = make_ssa_name (TREE_TYPE (orig_arg)); def = make_ssa_name (TREE_TYPE (orig_arg));
iter1 = make_ssa_name (TREE_TYPE (orig_arg)); iter1 = make_ssa_name (TREE_TYPE (orig_arg));
iter2 = make_ssa_name (TREE_TYPE (orig_arg)); if (incr_bb)
iter2 = make_ssa_name (TREE_TYPE (orig_arg));
gsi = gsi_after_labels (entry_bb); gsi = gsi_after_labels (entry_bb);
g = gimple_build_assign (def, orig_arg); g = gimple_build_assign (def, orig_arg);
gsi_insert_before (&gsi, g, GSI_NEW_STMT); gsi_insert_before (&gsi, g, GSI_NEW_STMT);
...@@ -1399,23 +1427,27 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1399,23 +1427,27 @@ simd_clone_adjust (struct cgraph_node *node)
else else
{ {
iter1 = make_ssa_name (orig_arg); iter1 = make_ssa_name (orig_arg);
iter2 = make_ssa_name (orig_arg); if (incr_bb)
iter2 = make_ssa_name (orig_arg);
} }
} }
if (def) if (def)
{ {
phi = create_phi_node (iter1, body_bb); phi = create_phi_node (iter1, body_bb);
add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION); add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION); if (incr_bb)
enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg)) {
? PLUS_EXPR : POINTER_PLUS_EXPR; add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg)) enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
? TREE_TYPE (orig_arg) : sizetype; ? PLUS_EXPR : POINTER_PLUS_EXPR;
tree addcst = simd_clone_linear_addend (node, i, addtype, tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
entry_bb); ? TREE_TYPE (orig_arg) : sizetype;
gsi = gsi_last_bb (incr_bb); tree addcst = simd_clone_linear_addend (node, i, addtype,
g = gimple_build_assign (iter2, code, iter1, addcst); entry_bb);
gsi_insert_before (&gsi, g, GSI_SAME_STMT); gsi = gsi_last_bb (incr_bb);
g = gimple_build_assign (iter2, code, iter1, addcst);
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
}
imm_use_iterator iter; imm_use_iterator iter;
use_operand_p use_p; use_operand_p use_p;
...@@ -1448,10 +1480,11 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1448,10 +1480,11 @@ simd_clone_adjust (struct cgraph_node *node)
{ {
tree rtype = TREE_TYPE (TREE_TYPE (orig_arg)); tree rtype = TREE_TYPE (TREE_TYPE (orig_arg));
iter1 = make_ssa_name (orig_arg); iter1 = make_ssa_name (orig_arg);
iter2 = make_ssa_name (orig_arg); if (incr_bb)
iter2 = make_ssa_name (orig_arg);
tree iter3 = make_ssa_name (rtype); tree iter3 = make_ssa_name (rtype);
tree iter4 = make_ssa_name (rtype); tree iter4 = make_ssa_name (rtype);
tree iter5 = make_ssa_name (rtype); tree iter5 = incr_bb ? make_ssa_name (rtype) : NULL_TREE;
gsi = gsi_after_labels (entry_bb); gsi = gsi_after_labels (entry_bb);
gimple *load gimple *load
= gimple_build_assign (iter3, build_simple_mem_ref (def)); = gimple_build_assign (iter3, build_simple_mem_ref (def));
...@@ -1462,24 +1495,30 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1462,24 +1495,30 @@ simd_clone_adjust (struct cgraph_node *node)
tree ptr = build_fold_addr_expr (array); tree ptr = build_fold_addr_expr (array);
phi = create_phi_node (iter1, body_bb); phi = create_phi_node (iter1, body_bb);
add_phi_arg (phi, ptr, preheader_edge, UNKNOWN_LOCATION); add_phi_arg (phi, ptr, preheader_edge, UNKNOWN_LOCATION);
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION); if (incr_bb)
g = gimple_build_assign (iter2, POINTER_PLUS_EXPR, iter1, {
TYPE_SIZE_UNIT (TREE_TYPE (iter3))); add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
gsi = gsi_last_bb (incr_bb); g = gimple_build_assign (iter2, POINTER_PLUS_EXPR, iter1,
gsi_insert_before (&gsi, g, GSI_SAME_STMT); TYPE_SIZE_UNIT (TREE_TYPE (iter3)));
gsi = gsi_last_bb (incr_bb);
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
}
phi = create_phi_node (iter4, body_bb); phi = create_phi_node (iter4, body_bb);
add_phi_arg (phi, iter3, preheader_edge, UNKNOWN_LOCATION); add_phi_arg (phi, iter3, preheader_edge, UNKNOWN_LOCATION);
add_phi_arg (phi, iter5, latch_edge, UNKNOWN_LOCATION); if (incr_bb)
enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (iter3)) {
? PLUS_EXPR : POINTER_PLUS_EXPR; add_phi_arg (phi, iter5, latch_edge, UNKNOWN_LOCATION);
tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (iter3)) enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (iter3))
? TREE_TYPE (iter3) : sizetype; ? PLUS_EXPR : POINTER_PLUS_EXPR;
tree addcst = simd_clone_linear_addend (node, i, addtype, tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (iter3))
entry_bb); ? TREE_TYPE (iter3) : sizetype;
g = gimple_build_assign (iter5, code, iter4, addcst); tree addcst = simd_clone_linear_addend (node, i, addtype,
gsi = gsi_last_bb (incr_bb); entry_bb);
gsi_insert_before (&gsi, g, GSI_SAME_STMT); g = gimple_build_assign (iter5, code, iter4, addcst);
gsi = gsi_last_bb (incr_bb);
gsi_insert_before (&gsi, g, GSI_SAME_STMT);
}
g = gimple_build_assign (build_simple_mem_ref (iter1), iter4); g = gimple_build_assign (build_simple_mem_ref (iter1), iter4);
gsi = gsi_after_labels (body_bb); gsi = gsi_after_labels (body_bb);
...@@ -1495,7 +1534,7 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1495,7 +1534,7 @@ simd_clone_adjust (struct cgraph_node *node)
FOR_EACH_IMM_USE_ON_STMT (use_p, iter) FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
SET_USE (use_p, iter1); SET_USE (use_p, iter1);
if (!TYPE_READONLY (rtype)) if (!TYPE_READONLY (rtype) && incr_bb)
{ {
tree v = make_ssa_name (rtype); tree v = make_ssa_name (rtype);
tree aref = build4 (ARRAY_REF, rtype, array, tree aref = build4 (ARRAY_REF, rtype, array,
...@@ -1511,7 +1550,8 @@ simd_clone_adjust (struct cgraph_node *node) ...@@ -1511,7 +1550,8 @@ simd_clone_adjust (struct cgraph_node *node)
} }
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
add_loop (loop, loop->header->loop_father); if (loop)
add_loop (loop, loop->header->loop_father);
update_ssa (TODO_update_ssa); update_ssa (TODO_update_ssa);
pop_cfun (); pop_cfun ();
......
2016-10-27 Jakub Jelinek <jakub@redhat.com>
PR middle-end/78025
* g++.dg/gomp/declare-simd-7.C: New test.
2016-10-27 Fritz Reese <fritzoreese@gmail.com> 2016-10-27 Fritz Reese <fritzoreese@gmail.com>
* gfortran.dg/dec_init_1.f90: Remove -fdump-tree-original. * gfortran.dg/dec_init_1.f90: Remove -fdump-tree-original.
......
// PR middle-end/78025
// { dg-do compile }
// { dg-additional-options "-O2" }
struct S { S (); ~S (); };
int bar1 (int, int, float &, S &, int *, int, int &, int &, int &, int &, int &);
int bar2 (int, int, float &, S &, int *, int, int &, int &, int &, int &, int &);
int bar3 (int, int, float &, S &, int *, int, int &, int &, int &, int &, int &) __attribute__((noreturn));
int bar4 (int, int, float &, S &, int *, int, int &, int &, int &, int &, int &) __attribute__((noreturn));
#pragma omp declare simd notinbranch uniform (b, c, d, e) aligned (e : 16) \
linear (f : 2) linear (ref (g) : 1) \
linear (val (h) : 1) linear (uval (i) : 1) \
linear (k : 4)
int
foo1 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j, int k)
{
return bar1 (a, b, c, d, e, f, g, h, i, j, k);
}
#pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
linear (f : 2) linear (ref (g) : 1) \
linear (val (h) : 1) linear (uval (i) : 1) \
linear (k : 4)
int
foo2 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j, int k)
{
return bar2 (a, b, c, d, e, f, g, h, i, j, k);
}
#pragma omp declare simd notinbranch uniform (b, c, d, e) aligned (e : 16) \
linear (f : 2) linear (ref (g) : 1) \
linear (val (h) : 1) linear (uval (i) : 1) \
linear (k : 4)
int
foo3 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j, int k)
{
return bar3 (a, b, c, d, e, f, g, h, i, j, k);
}
#pragma omp declare simd inbranch uniform (b, c, d, e) aligned (e : 16) \
linear (f : 2) linear (ref (g) : 1) \
linear (val (h) : 1) linear (uval (i) : 1) \
linear (k : 4)
int
foo4 (int a, int b, float c, S d, int *e, int f, int &g, int &h, int &i, int j, int k)
{
return bar4 (a, b, c, d, e, f, g, h, i, j, k);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment