Commit 684f25f4 by Alexandre Oliva Committed by Alexandre Oliva

re PR debug/42604 (VTA ICE in the vectorizer)

gcc/ChangeLog:
PR debug/42604
PR debug/42395
* tree-vect-loop-manip.c (adjust_info): New type.
(adjust_vec): New pointer to vector.
(adjust_debug_stmts_now, adjust_vec_debug_stmts): New.
(adjust_debug_stmts, adjust_phi_and_debug_stmts): New.
(slpeel_update_phis_for_duplicate_loop): Use them.
(slpeel_update_phi_nodes_for_guard1): Likewise.
(slpeel_update_phi_nodes_for_guard2): Likewise.
(slpeel_tree_peel_loop_to_edge): Likewise.
(vect_update_ivs_after_vectorizer): Likewise.
gcc/testsuite/ChangeLog:
PR debug/42604
PR debug/42395
* gcc.dg/vect/pr42604.c: New.
* gcc.dg/vect/pr42395.c: New.

From-SVN: r155761
parent 0e00563c
2010-01-09 Alexandre Oliva <aoliva@redhat.com>
PR debug/42604
PR debug/42395
* tree-vect-loop-manip.c (adjust_info): New type.
(adjust_vec): New pointer to vector.
(adjust_debug_stmts_now, adjust_vec_debug_stmts): New.
(adjust_debug_stmts, adjust_phi_and_debug_stmts): New.
(slpeel_update_phis_for_duplicate_loop): Use them.
(slpeel_update_phi_nodes_for_guard1): Likewise.
(slpeel_update_phi_nodes_for_guard2): Likewise.
(slpeel_tree_peel_loop_to_edge): Likewise.
(vect_update_ivs_after_vectorizer): Likewise.
2010-01-09 Alexandre Oliva <aoliva@redhat.com>
* vec.h (DEF_VEC_ALLOC_FUNC_O_STACK): Drop excess paren.
(DEF_VEC_ALLOC_FUNC_I_STACK): Likewise.
......
2010-01-09 Alexandre Oliva <aoliva@redhat.com>
PR debug/42604
PR debug/42395
* gcc.dg/vect/pr42604.c: New.
* gcc.dg/vect/pr42395.c: New.
2010-01-09 Richard Guenther <rguenther@suse.de>
PR middle-end/42512
......
/* PR debug/42395 */
/* { dg-do compile } */
/* { dg-options "-O3 -ftree-vectorize -g" } */
void foo(int j, int *A)
{
int i;
for (i = 0; i < j; i ++) A[i] = i;
for (; i < 4096; i ++) A[i] = 0;
}
/* PR debug/42604 */
/* { dg-do compile } */
/* { dg-options "-O3 -ftree-vectorize -g -ffast-math" } */
unsigned *d;
unsigned short e;
int f;
float h[3][4];
void
test (unsigned short *b)
{
int a, c, i;
float g[3];
unsigned j[32] = { 10, 0x63707274 };
for (i = 0; i < (int) j[0]; i++)
{
j[i * 3 + 2] = d[0];
d[0] += (j[i * 3 + 3] + 3) & -4;
}
for (a = 0; a < e; a++)
{
g[0] = g[1] = g[2] = 0;
for (c = 0; c < f; c++)
{
g[0] += h[0][c] * b[c];
g[1] += h[1][c] * b[c];
}
for (c = 0; c < 3; c++)
b[c] = 0 > ((int) g[c] < 65535 ? ((int) g[c]) : 65535)
? 0 : ((int) g[c]) < 65535 ? (int) g[c] : 65535;
}
}
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -113,6 +113,131 @@ rename_variables_in_loop (struct loop *loop)
free (bbs);
}
typedef struct
{
tree from, to;
basic_block bb;
} adjust_info;
DEF_VEC_O(adjust_info);
DEF_VEC_ALLOC_O_STACK(adjust_info);
#define VEC_adjust_info_stack_alloc(alloc) VEC_stack_alloc (adjust_info, alloc)
/* A stack of values to be adjusted in debug stmts. We have to
process them LIFO, so that the closest substitution applies. If we
processed them FIFO, without the stack, we might substitute uses
with a PHI DEF that would soon become non-dominant, and when we got
to the suitable one, it wouldn't have anything to substitute any
more. */
static VEC(adjust_info, stack) *adjust_vec;
/* Adjust any debug stmts that referenced AI->from values to use the
loop-closed AI->to, if the references are dominated by AI->bb and
not by the definition of AI->from. */
static void
adjust_debug_stmts_now (adjust_info *ai)
{
basic_block bbphi = ai->bb;
tree orig_def = ai->from;
tree new_def = ai->to;
imm_use_iterator imm_iter;
gimple stmt;
basic_block bbdef = gimple_bb (SSA_NAME_DEF_STMT (orig_def));
gcc_assert (dom_info_available_p (CDI_DOMINATORS));
/* Adjust any debug stmts that held onto non-loop-closed
references. */
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, orig_def)
{
use_operand_p use_p;
basic_block bbuse;
if (!is_gimple_debug (stmt))
continue;
gcc_assert (gimple_debug_bind_p (stmt));
bbuse = gimple_bb (stmt);
if ((bbuse == bbphi
|| dominated_by_p (CDI_DOMINATORS, bbuse, bbphi))
&& !(bbuse == bbdef
|| dominated_by_p (CDI_DOMINATORS, bbuse, bbdef)))
{
if (new_def)
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
SET_USE (use_p, new_def);
else
{
gimple_debug_bind_reset_value (stmt);
update_stmt (stmt);
}
}
}
}
/* Adjust debug stmts as scheduled before. */
static void
adjust_vec_debug_stmts (void)
{
if (!MAY_HAVE_DEBUG_STMTS)
return;
gcc_assert (adjust_vec);
while (!VEC_empty (adjust_info, adjust_vec))
{
adjust_debug_stmts_now (VEC_last (adjust_info, adjust_vec));
VEC_pop (adjust_info, adjust_vec);
}
VEC_free (adjust_info, stack, adjust_vec);
}
/* Adjust any debug stmts that referenced FROM values to use the
loop-closed TO, if the references are dominated by BB and not by
the definition of FROM. If adjust_vec is non-NULL, adjustments
will be postponed until adjust_vec_debug_stmts is called. */
static void
adjust_debug_stmts (tree from, tree to, basic_block bb)
{
adjust_info ai;
if (MAY_HAVE_DEBUG_STMTS && TREE_CODE (from) == SSA_NAME
&& SSA_NAME_VAR (from) != gimple_vop (cfun))
{
ai.from = from;
ai.to = to;
ai.bb = bb;
if (adjust_vec)
VEC_safe_push (adjust_info, stack, adjust_vec, &ai);
else
adjust_debug_stmts_now (&ai);
}
}
/* Change E's phi arg in UPDATE_PHI to NEW_DEF, and record information
to adjust any debug stmts that referenced the old phi arg,
presumably non-loop-closed references left over from other
transformations. */
static void
adjust_phi_and_debug_stmts (gimple update_phi, edge e, tree new_def)
{
tree orig_def = PHI_ARG_DEF_FROM_EDGE (update_phi, e);
SET_PHI_ARG_DEF (update_phi, e->dest_idx, new_def);
if (MAY_HAVE_DEBUG_STMTS)
adjust_debug_stmts (orig_def, PHI_RESULT (update_phi),
gimple_bb (update_phi));
}
/* Update the PHI nodes of NEW_LOOP.
......@@ -195,13 +320,15 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
/* An ordinary ssa name defined in the loop. */
add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
/* Drop any debug references outside the loop, if they would
become ill-formed SSA. */
adjust_debug_stmts (def, NULL, single_exit (orig_loop)->dest);
/* step 3 (case 1). */
if (!after)
{
gcc_assert (new_loop_exit_e == orig_entry_e);
SET_PHI_ARG_DEF (phi_orig,
new_loop_exit_e->dest_idx,
new_ssa_name);
adjust_phi_and_debug_stmts (phi_orig, new_loop_exit_e, new_ssa_name);
}
}
}
......@@ -413,7 +540,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
/* 1.3. Update phi in successor block. */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
|| PHI_ARG_DEF_FROM_EDGE (update_phi, e) == guard_arg);
SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi));
adjust_phi_and_debug_stmts (update_phi, e, PHI_RESULT (new_phi));
update_phi2 = new_phi;
......@@ -431,7 +558,8 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
/* 2.3. Update phi in successor of NEW_EXIT_BB: */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi));
adjust_phi_and_debug_stmts (update_phi2, new_exit_e,
PHI_RESULT (new_phi));
/* 2.4. Record the newly created name with set_current_def.
We want to find a name such that
......@@ -560,7 +688,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
/* 1.3. Update phi in successor block. */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
SET_PHI_ARG_DEF (update_phi, e->dest_idx, PHI_RESULT (new_phi));
adjust_phi_and_debug_stmts (update_phi, e, PHI_RESULT (new_phi));
update_phi2 = new_phi;
......@@ -575,7 +703,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
/* 2.3. Update phi in successor of NEW_EXIT_BB: */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi));
adjust_phi_and_debug_stmts (update_phi2, new_exit_e,
PHI_RESULT (new_phi));
/** 3. Handle loop-closed-ssa-form phis for first loop **/
......@@ -612,7 +741,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
/* 3.4. Update phi in successor of GUARD_BB: */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
== guard_arg);
SET_PHI_ARG_DEF (update_phi2, guard_edge->dest_idx, PHI_RESULT (new_phi));
adjust_phi_and_debug_stmts (update_phi2, guard_edge,
PHI_RESULT (new_phi));
}
}
......@@ -1083,6 +1213,12 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
return NULL;
}
if (MAY_HAVE_DEBUG_STMTS)
{
gcc_assert (!adjust_vec);
adjust_vec = VEC_alloc (adjust_info, stack, 32);
}
if (e == exit_e)
{
/* NEW_LOOP was placed after LOOP. */
......@@ -1278,6 +1414,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
if (update_first_loop_count)
slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
adjust_vec_debug_stmts ();
BITMAP_FREE (definitions);
delete_update_ssa ();
......@@ -1668,7 +1806,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
true, GSI_SAME_STMT);
/* Fix phi expressions in the successor bb. */
SET_PHI_ARG_DEF (phi1, update_e->dest_idx, ni_name);
adjust_phi_and_debug_stmts (phi1, update_e, ni_name);
}
}
......@@ -2399,7 +2537,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo, bool do_versioning,
arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
add_phi_arg (new_phi, arg, new_exit_e,
gimple_phi_arg_location_from_edge (orig_phi, e));
SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi));
adjust_phi_and_debug_stmts (orig_phi, e, PHI_RESULT (new_phi));
}
/* End loop-exit-fixes after versioning. */
......
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