]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/58553 (New fail in PASS->FAIL: gcc.c-torture/execute/memcpy...
authorRichard Biener <rguenther@suse.de>
Tue, 1 Oct 2013 07:41:10 +0000 (07:41 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 1 Oct 2013 07:41:10 +0000 (07:41 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr58553.c [new file with mode: 0644]
gcc/tree-loop-distribution.c

index 7c9a6c513ae94d78923a8762af8e891853f90bf5..3a810c847c1b8a392dd061e1ed23aec642ae89a9 100644 (file)
@@ -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_".
index 3b22081878eb4ef9b6103a28ff59a73ef7e21330..37af098de5d25779792f182b9400ef9c8938a283 100644 (file)
@@ -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 (file)
index 0000000..542bf3f
--- /dev/null
@@ -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;
+}
index 964131a1950e6dc37b79124d97fbf7d16dda5b84..fe2f7b65b590b6214429665c33f080e82f97e08b 100644 (file)
@@ -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;
     }
 }