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>
* builtins.c (expand_builtin_nonlocal_goto): Avoid evaluating
......@@ -1107,7 +1107,7 @@ simd_clone_adjust (struct cgraph_node *node)
return values accordingly. */
tree iter = create_tmp_var (unsigned_type_node, "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);
adjustments.release ();
......@@ -1121,10 +1121,16 @@ simd_clone_adjust (struct cgraph_node *node)
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
iteration increment and the condition/branch. */
if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
{
basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
basic_block incr_bb = create_empty_bb (orig_exit);
incr_bb = create_empty_bb (orig_exit);
add_bb_to_loop (incr_bb, body_bb->loop_father);
/* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
flag. Set it now to be a FALLTHRU_EDGE. */
......@@ -1136,24 +1142,36 @@ simd_clone_adjust (struct cgraph_node *node)
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 = 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,
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). */
struct loop *loop = alloc_loop ();
/* 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;
}
/* Branch around the body if the mask applies. */
if (node->simdclone->inbranch)
{
gimple_stmt_iterator gsi = gsi_last_bb (loop->header);
gsi = gsi_last_bb (loop->header);
tree mask_array
= node->simdclone->args[node->simdclone->nargs - 1].simd_array;
tree mask;
......@@ -1227,16 +1245,20 @@ simd_clone_adjust (struct cgraph_node *node)
FALLTHRU_EDGE (loop->header)->flags = EDGE_FALSE_VALUE;
}
basic_block latch_bb = NULL;
basic_block new_exit_bb = NULL;
/* Generate the condition. */
g = gimple_build_cond (LT_EXPR,
iter2,
if (incr_bb)
{
gsi = gsi_last_bb (incr_bb);
g = gimple_build_cond (LT_EXPR, iter2,
build_int_cst (unsigned_type_node,
node->simdclone->simdlen),
NULL, NULL);
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
e = split_block (incr_bb, gsi_stmt (gsi));
basic_block latch_bb = e->dest;
basic_block new_exit_bb;
edge e = split_block (incr_bb, gsi_stmt (gsi));
latch_bb = e->dest;
new_exit_bb = split_block_after_labels (latch_bb)->dest;
loop->latch = latch_bb;
......@@ -1247,12 +1269,16 @@ simd_clone_adjust (struct cgraph_node *node)
change the flags.
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);
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,
UNKNOWN_LOCATION);
if (incr_bb)
{
latch_edge = single_succ_edge (latch_bb);
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
/* Generate the new return. */
......@@ -1271,6 +1297,7 @@ simd_clone_adjust (struct cgraph_node *node)
}
g = gimple_build_return (retval);
gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
}
/* Handle aligned clauses by replacing default defs of the aligned
uniform args with __builtin_assume_aligned (arg_N(D), alignment)
......@@ -1386,6 +1413,7 @@ simd_clone_adjust (struct cgraph_node *node)
{
def = make_ssa_name (TREE_TYPE (orig_arg));
iter1 = make_ssa_name (TREE_TYPE (orig_arg));
if (incr_bb)
iter2 = make_ssa_name (TREE_TYPE (orig_arg));
gsi = gsi_after_labels (entry_bb);
g = gimple_build_assign (def, orig_arg);
......@@ -1399,6 +1427,7 @@ simd_clone_adjust (struct cgraph_node *node)
else
{
iter1 = make_ssa_name (orig_arg);
if (incr_bb)
iter2 = make_ssa_name (orig_arg);
}
}
......@@ -1406,6 +1435,8 @@ simd_clone_adjust (struct cgraph_node *node)
{
phi = create_phi_node (iter1, body_bb);
add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
if (incr_bb)
{
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
? PLUS_EXPR : POINTER_PLUS_EXPR;
......@@ -1416,6 +1447,7 @@ simd_clone_adjust (struct cgraph_node *node)
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;
use_operand_p use_p;
......@@ -1448,10 +1480,11 @@ simd_clone_adjust (struct cgraph_node *node)
{
tree rtype = TREE_TYPE (TREE_TYPE (orig_arg));
iter1 = make_ssa_name (orig_arg);
if (incr_bb)
iter2 = make_ssa_name (orig_arg);
tree iter3 = 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);
gimple *load
= gimple_build_assign (iter3, build_simple_mem_ref (def));
......@@ -1462,14 +1495,19 @@ simd_clone_adjust (struct cgraph_node *node)
tree ptr = build_fold_addr_expr (array);
phi = create_phi_node (iter1, body_bb);
add_phi_arg (phi, ptr, preheader_edge, UNKNOWN_LOCATION);
if (incr_bb)
{
add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
g = gimple_build_assign (iter2, POINTER_PLUS_EXPR, iter1,
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);
add_phi_arg (phi, iter3, preheader_edge, UNKNOWN_LOCATION);
if (incr_bb)
{
add_phi_arg (phi, iter5, latch_edge, UNKNOWN_LOCATION);
enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (iter3))
? PLUS_EXPR : POINTER_PLUS_EXPR;
......@@ -1480,6 +1518,7 @@ simd_clone_adjust (struct cgraph_node *node)
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);
gsi = gsi_after_labels (body_bb);
......@@ -1495,7 +1534,7 @@ simd_clone_adjust (struct cgraph_node *node)
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
SET_USE (use_p, iter1);
if (!TYPE_READONLY (rtype))
if (!TYPE_READONLY (rtype) && incr_bb)
{
tree v = make_ssa_name (rtype);
tree aref = build4 (ARRAY_REF, rtype, array,
......@@ -1511,6 +1550,7 @@ simd_clone_adjust (struct cgraph_node *node)
}
calculate_dominance_info (CDI_DOMINATORS);
if (loop)
add_loop (loop, loop->header->loop_father);
update_ssa (TODO_update_ssa);
......
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>
* 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