re PR tree-optimization/59058 (wrong code at -O3 on x86_64-linux-gnu (affecting gcc 4.6 to trunk))

2013-11-21  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/59058
	* tree-loop-distribution.c (struct partition_s): Add plus_one
	member.
	(build_size_arg_loc): Apply niter adjustment here.
	(generate_memset_builtin): Adjust.
	(generate_memcpy_builtin): Likewise.
	(classify_partition): Do not use number_of_exit_cond_executions
	but record whether niter needs to be adjusted.

From-SVN: r205197
This commit is contained in:
Richard Biener 2013-11-21 09:15:05 +00:00 committed by Richard Biener
parent d091cd30a1
commit d995e887cb
2 changed files with 32 additions and 12 deletions

View file

@ -1,3 +1,14 @@
2013-11-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/59058
* tree-loop-distribution.c (struct partition_s): Add plus_one
member.
(build_size_arg_loc): Apply niter adjustment here.
(generate_memset_builtin): Adjust.
(generate_memcpy_builtin): Likewise.
(classify_partition): Do not use number_of_exit_cond_executions
but record whether niter needs to be adjusted.
2013-11-21 Eric Botcazou <ebotcazou@adacore.com>
* tree-ssa-tail-merge.c (stmt_local_def): Return false if the statement

View file

@ -480,6 +480,7 @@ typedef struct partition_s
data_reference_p main_dr;
data_reference_p secondary_dr;
tree niter;
bool plus_one;
} *partition_t;
@ -703,13 +704,16 @@ generate_loops_for_partition (struct loop *loop, partition_t partition,
/* Build the size argument for a memory operation call. */
static tree
build_size_arg_loc (location_t loc, data_reference_p dr, tree nb_iter)
build_size_arg_loc (location_t loc, data_reference_p dr, tree nb_iter,
bool plus_one)
{
tree size;
size = fold_build2_loc (loc, MULT_EXPR, sizetype,
fold_convert_loc (loc, sizetype, nb_iter),
tree size = fold_convert_loc (loc, sizetype, nb_iter);
if (plus_one)
size = size_binop (PLUS_EXPR, size, size_one_node);
size = fold_build2_loc (loc, MULT_EXPR, sizetype, size,
TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))));
return fold_convert_loc (loc, size_type_node, size);
size = fold_convert_loc (loc, size_type_node, size);
return size;
}
/* Build an address argument for a memory operation call. */
@ -781,7 +785,8 @@ generate_memset_builtin (struct loop *loop, partition_t partition)
/* The new statements will be placed before LOOP. */
gsi = gsi_last_bb (loop_preheader_edge (loop)->src);
nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter);
nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter,
partition->plus_one);
nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
mem = build_addr_arg_loc (loc, partition->main_dr, nb_bytes);
@ -837,7 +842,8 @@ generate_memcpy_builtin (struct loop *loop, partition_t partition)
/* The new statements will be placed before LOOP. */
gsi = gsi_last_bb (loop_preheader_edge (loop)->src);
nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter);
nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter,
partition->plus_one);
nb_bytes = force_gimple_operand_gsi (&gsi, nb_bytes, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
dest = build_addr_arg_loc (loc, partition->main_dr, nb_bytes);
@ -980,11 +986,13 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
tree nb_iter;
data_reference_p single_load, single_store;
bool volatiles_p = false;
bool plus_one = false;
partition->kind = PKIND_NORMAL;
partition->main_dr = NULL;
partition->secondary_dr = NULL;
partition->niter = NULL_TREE;
partition->plus_one = false;
EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi)
{
@ -1047,13 +1055,12 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
if (!single_store)
return;
if (!dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src,
gimple_bb (DR_STMT (single_store))))
nb_iter = number_of_latch_executions (loop);
else
nb_iter = number_of_exit_cond_executions (loop);
nb_iter = number_of_latch_executions (loop);
if (!nb_iter || nb_iter == chrec_dont_know)
return;
if (dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src,
gimple_bb (DR_STMT (single_store))))
plus_one = true;
if (single_store && !single_load)
{
@ -1075,6 +1082,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
partition->kind = PKIND_MEMSET;
partition->main_dr = single_store;
partition->niter = nb_iter;
partition->plus_one = plus_one;
}
else if (single_store && single_load)
{
@ -1132,6 +1140,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition)
partition->main_dr = single_store;
partition->secondary_dr = single_load;
partition->niter = nb_iter;
partition->plus_one = plus_one;
}
}