diff options
author | Richard Biener <rguenther@suse.de> | 2013-10-01 07:41:10 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-10-01 07:41:10 +0000 |
commit | 818625cf9eb14c87e7ea46471321c38fda7cb6a5 (patch) | |
tree | 4364870cc24e53f1deed7befaaf0e34bc35fad06 /gcc | |
parent | 2cb01a397200b182e28f9d91dfde104e3a3895d1 (diff) | |
download | gcc-818625cf9eb14c87e7ea46471321c38fda7cb6a5.zip gcc-818625cf9eb14c87e7ea46471321c38fda7cb6a5.tar.gz gcc-818625cf9eb14c87e7ea46471321c38fda7cb6a5.tar.bz2 |
re PR tree-optimization/58553 (New fail in PASS->FAIL: gcc.c-torture/execute/memcpy-2.c execution on arm and aarch64)
2013-10-01 Richard Biener <rguenther@suse.de>
PR tree-optimization/58553
* tree-loop-distribution.c (struct partition_s): Add niter member.
(classify_partition): Populate niter member for the partition
and properly identify whether the relevant store happens before
or after the loop exit.
(generate_memset_builtin): Use niter member from the partition.
(generate_memcpy_builtin): Likewise.
* gcc.dg/torture/pr58553.c: New testcase.
From-SVN: r203054
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr58553.c | 28 | ||||
-rw-r--r-- | gcc/tree-loop-distribution.c | 35 |
4 files changed, 62 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c9a6c5..3a810c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-10-01 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58553 + * tree-loop-distribution.c (struct partition_s): Add niter member. + (classify_partition): Populate niter member for the partition + and properly identify whether the relevant store happens before + or after the loop exit. + (generate_memset_builtin): Use niter member from the partition. + (generate_memcpy_builtin): Likewise. + 2013-09-30 Richard Sandiford <rdsandiford@googlemail.com> * vec.h (vec_prefix, vec): Prefix member names with "m_". diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b22081..37af098 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-10-01 Richard Biener <rguenther@suse.de> + + PR tree-optimization/58553 + * gcc.dg/torture/pr58553.c: New testcase. + 2013-09-30 Jakub Jelinek <jakub@redhat.com> PR middle-end/58564 diff --git a/gcc/testsuite/gcc.dg/torture/pr58553.c b/gcc/testsuite/gcc.dg/torture/pr58553.c new file mode 100644 index 0000000..542bf3f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58553.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#define MAX_LENGTH 96 +#define SEQUENCE_LENGTH 31 + +static struct { + char buf[MAX_LENGTH + 1]; +} u1, u2; + +extern void abort (void); + +int main () +{ + int i; + char c; + + for (i = 0, c = 'A'; i < MAX_LENGTH; i++, c++) + { + u1.buf[i] = 'a'; + if (c >= 'A' + SEQUENCE_LENGTH) + c = 'A'; + u2.buf[i] = c; + } + if (u1.buf[MAX_LENGTH] != '\0') + abort (); + + return 0; +} diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 964131a..fe2f7b6 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -569,6 +569,7 @@ typedef struct partition_s /* data-references a kind != PKIND_NORMAL partition is about. */ data_reference_p main_dr; data_reference_p secondary_dr; + tree niter; } *partition_t; @@ -848,21 +849,17 @@ generate_memset_builtin (struct loop *loop, partition_t partition) { gimple_stmt_iterator gsi; gimple stmt, fn_call; - tree nb_iter, mem, fn, nb_bytes; + tree mem, fn, nb_bytes; location_t loc; tree val; stmt = DR_STMT (partition->main_dr); loc = gimple_location (stmt); - if (gimple_bb (stmt) == loop->latch) - nb_iter = number_of_latch_executions (loop); - else - nb_iter = number_of_exit_cond_executions (loop); /* 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, nb_iter); + nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter); 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); @@ -908,21 +905,17 @@ generate_memcpy_builtin (struct loop *loop, partition_t partition) { gimple_stmt_iterator gsi; gimple stmt, fn_call; - tree nb_iter, dest, src, fn, nb_bytes; + tree dest, src, fn, nb_bytes; location_t loc; enum built_in_function kind; stmt = DR_STMT (partition->main_dr); loc = gimple_location (stmt); - if (gimple_bb (stmt) == loop->latch) - nb_iter = number_of_latch_executions (loop); - else - nb_iter = number_of_exit_cond_executions (loop); /* 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, nb_iter); + nb_bytes = build_size_arg_loc (loc, partition->main_dr, partition->niter); 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); @@ -1125,6 +1118,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) partition->kind = PKIND_NORMAL; partition->main_dr = NULL; partition->secondary_dr = NULL; + partition->niter = NULL_TREE; EXECUTE_IF_SET_IN_BITMAP (partition->stmts, 0, i, bi) { @@ -1151,10 +1145,6 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) || !flag_tree_loop_distribute_patterns) return; - nb_iter = number_of_exit_cond_executions (loop); - if (!nb_iter || nb_iter == chrec_dont_know) - return; - /* Detect memset and memcpy. */ single_load = NULL; single_store = NULL; @@ -1193,6 +1183,17 @@ 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); + if (!nb_iter || nb_iter == chrec_dont_know) + return; + if (single_store && !single_load) { gimple stmt = DR_STMT (single_store); @@ -1212,6 +1213,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) return; partition->kind = PKIND_MEMSET; partition->main_dr = single_store; + partition->niter = nb_iter; } else if (single_store && single_load) { @@ -1268,6 +1270,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) partition->kind = PKIND_MEMCPY; partition->main_dr = single_store; partition->secondary_dr = single_load; + partition->niter = nb_iter; } } |