aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-10-01 07:41:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-10-01 07:41:10 +0000
commit818625cf9eb14c87e7ea46471321c38fda7cb6a5 (patch)
tree4364870cc24e53f1deed7befaaf0e34bc35fad06 /gcc
parent2cb01a397200b182e28f9d91dfde104e3a3895d1 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58553.c28
-rw-r--r--gcc/tree-loop-distribution.c35
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;
}
}