re PR tree-optimization/82574 (wrong code at -O3 on x86_64-linux-gnu)
authorBin Cheng <bin.cheng@arm.com>
Wed, 18 Oct 2017 15:56:15 +0000 (15:56 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Wed, 18 Oct 2017 15:56:15 +0000 (15:56 +0000)
PR tree-optimization/82574
* tree-loop-distribution.c (find_single_drs): New parameter.  Check
that data reference must be executed exactly once per iteration
against the outermost loop in nest.
(classify_partition): Update call to above function.

gcc/testsuite
* gcc.dg/tree-ssa/pr82574.c: New test.

From-SVN: r253857

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

index 51ad45e7964e7eb5776cac8fa951ee322659d1a2..1eee85d3328325a905efab28d35db1a0bceedd16 100644 (file)
@@ -1,3 +1,11 @@
+2017-10-18  Bin Cheng  <bin.cheng@arm.com>
+
+       PR tree-optimization/82574
+       * tree-loop-distribution.c (find_single_drs): New parameter.  Check
+       that data reference must be executed exactly once per iteration
+       against the outermost loop in nest.
+       (classify_partition): Update call to above function.
+
 2017-10-18  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82591
index 37454e1d5b531735e9af9e478bc4b37d3738301b..d642a6aba80a5f66327ddf30223cd19f8843d69d 100644 (file)
@@ -1,3 +1,8 @@
+2017-10-18  Bin Cheng  <bin.cheng@arm.com>
+
+       PR tree-optimization/82574
+       * gcc.dg/tree-ssa/pr82574.c: New test.
+
 2017-10-18  Martin Liska  <mliska@suse.cz>
 
        * gcc.dg/tree-prof/switch-case-2.c: Scan IPA profile dump
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr82574.c b/gcc/testsuite/gcc.dg/tree-ssa/pr82574.c
new file mode 100644 (file)
index 0000000..8fc4596
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+
+unsigned char a, b, c, d[200][200];
+
+void abort (void);
+
+int main ()
+{
+  for (; a < 200; a++)
+    for (b = 0; b < 200; b++)
+      if (c)
+       d[a][b] = 1;
+
+  if ((c && d[0][0] != 1) || (!c && d[0][0] != 0))
+    abort ();
+
+  return 0;
+}
index 5e835be779da44d838eee787267e4ee6a75ab4c7..6abb7e43421074d64b3dcd501850ff32071a72a7 100644 (file)
@@ -1283,12 +1283,12 @@ build_rdg_partition_for_vertex (struct graph *rdg, int v)
   return partition;
 }
 
-/* Given PARTITION of RDG, record single load/store data references for
-   builtin partition in SRC_DR/DST_DR, return false if there is no such
+/* Given PARTITION of LOOP and RDG, record single load/store data references
+   for builtin partition in SRC_DR/DST_DR, return false if there is no such
    data references.  */
 
 static bool
-find_single_drs (struct graph *rdg, partition *partition,
+find_single_drs (struct loop *loop, struct graph *rdg, partition *partition,
                 data_reference_p *dst_dr, data_reference_p *src_dr)
 {
   unsigned i;
@@ -1344,10 +1344,12 @@ find_single_drs (struct graph *rdg, partition *partition,
       && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (single_st), 1)))
     return false;
 
-  /* Data reference must be executed exactly once per iteration.  */
+  /* Data reference must be executed exactly once per iteration of each
+     loop in the loop nest.  We only need to check dominance information
+     against the outermost one in a perfect loop nest because a bb can't
+     dominate outermost loop's latch without dominating inner loop's.  */
   basic_block bb_st = gimple_bb (DR_STMT (single_st));
-  struct loop *inner = bb_st->loop_father;
-  if (!dominated_by_p (CDI_DOMINATORS, inner->latch, bb_st))
+  if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb_st))
     return false;
 
   if (single_ld)
@@ -1365,14 +1367,16 @@ find_single_drs (struct graph *rdg, partition *partition,
 
       /* Load and store must be in the same loop nest.  */
       basic_block bb_ld = gimple_bb (DR_STMT (single_ld));
-      if (inner != bb_ld->loop_father)
+      if (bb_st->loop_father != bb_ld->loop_father)
        return false;
 
-      /* Data reference must be executed exactly once per iteration.  */
-      if (!dominated_by_p (CDI_DOMINATORS, inner->latch, bb_ld))
+      /* Data reference must be executed exactly once per iteration.
+        Same as single_st, we only need to check against the outermost
+        loop.  */
+      if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb_ld))
        return false;
 
-      edge e = single_exit (inner);
+      edge e = single_exit (bb_st->loop_father);
       bool dom_ld = dominated_by_p (CDI_DOMINATORS, e->src, bb_ld);
       bool dom_st = dominated_by_p (CDI_DOMINATORS, e->src, bb_st);
       if (dom_ld != dom_st)
@@ -1611,7 +1615,7 @@ classify_partition (loop_p loop, struct graph *rdg, partition *partition,
     return;
 
   /* Find single load/store data references for builtin partition.  */
-  if (!find_single_drs (rdg, partition, &single_st, &single_ld))
+  if (!find_single_drs (loop, rdg, partition, &single_st, &single_ld))
     return;
 
   /* Classify the builtin kind.  */