While building a data dependency graph for loop a ddg edge for some pair
of instructions with inter-loop dependency should be created only if
there is no edge for intra-loop dependency between these instructions.
Creating both of edges leads sometimes to the fact that function
generate_reg_moves creates a redundant register renaming, and some
instruction receives wrong register value from previous iteration.
Overall, this gives a miscompilation.

The add_inter_loop_mem_dep(from,to) function is called only when no
inter-loop "from->to" edge exists, but this function sometimes creates
backward "to->from" edges.  This patch prevents these backward edges to
be redundant, it allows to create such edge only when there is no
inter-loop one.

2011-07-20  Roman Zhuykov  <zhr...@ispras.ru>
        * ddg.c (add_intra_loop_mem_dep): Add new parameter (from_index).
        Use it to check whether backward edge is redundant.
        (build_intra_loop_deps): Update call to add_intra_loop_mem_dep.
---
 gcc/ddg.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/gcc/ddg.c b/gcc/ddg.c
index 2bb2cc1..5d0a401 100644
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -418,7 +418,7 @@ add_intra_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, 
ddg_node_ptr to)
 /* Given two nodes, analyze their RTL insns and add inter-loop mem deps
    to ddg G.  */
 static void
-add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to)
+add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, ddg_node_ptr to, int 
from_index)
 {
   if (!insns_may_alias_p (from->insn, to->insn))
     /* Do not create edge if memory references have disjoint alias sets.  */
@@ -442,10 +442,13 @@ add_inter_loop_mem_dep (ddg_ptr g, ddg_node_ptr from, 
ddg_node_ptr to)
       else if (from->cuid != to->cuid)
        {
          create_ddg_dep_no_link (g, from, to, ANTI_DEP, MEM_DEP, 1);
-         if (DEBUG_INSN_P (from->insn) || DEBUG_INSN_P (to->insn))
-           create_ddg_dep_no_link (g, to, from, ANTI_DEP, MEM_DEP, 1);
-         else
-           create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
+         if (! TEST_BIT (to->successors, from_index))
+           {
+             if (DEBUG_INSN_P (from->insn) || DEBUG_INSN_P (to->insn))
+               create_ddg_dep_no_link (g, to, from, ANTI_DEP, MEM_DEP, 1);
+             else
+               create_ddg_dep_no_link (g, to, from, TRUE_DEP, MEM_DEP, 1);
+           }
        }
     }
 
@@ -511,7 +514,7 @@ build_intra_loop_deps (ddg_ptr g)
                  /* Don't bother calculating inter-loop dep if an intra-loop 
dep
                     already exists.  */
                  if (! TEST_BIT (dest_node->successors, j))
-                   add_inter_loop_mem_dep (g, dest_node, j_node);
+                   add_inter_loop_mem_dep (g, dest_node, j_node, i);
                  /* If -fmodulo-sched-allow-regmoves
                     is set certain anti-dep edges are not created.
                     It might be that these anti-dep edges are on the
-- 
Roman Zhuykov
zhr...@ispras.ru

Reply via email to