At present, there are several places in the code where, while
analyzing the outer loop in a nested pair of loops, when we're
traversing bbs in a loop for some analysis purpose, the analysis
crosses the inter-loop boundary into the inner loop, thus drawing
erroneous conclusions on the outer loop based on inner-loop
information.

This patch adds fixes for two functions:
  - `vect_stmt_relevant_p'
  - `vect_analyze_early_break_dependences'

For `vect_stmt_relevant_p', we mark any induction variable definitions
for multi-exit loops as relevant.  We should ensure the induction
variable is associated with the current loop in question.  We thus
check if the loop contains some inner loop.  If not, we needn't apply
any further logic.  Else, we retrieve the statement's enclosing bb and
from that, which loop the bb is associated with.  This loop is then
compared with the one being considered in relevancy analysis.  Only if
the two loops match do we mark it as relevant.

For `vect_analyze_early_break_dependences', we consider the allowable
structure of nested loops for vectorization.  This states that nested
loops should be of the following form:

                        (pre-header)
                           |
                          header <---+
                           |         |
                          inner-loop |
                           |         |
                          tail ------+
                           |
                        (exit-bb)

That is, there should be no basic block separating the inner-loop from
either the head or tail bbs.  This constraint on the allowed types of
nested loops facilitates the correction of such errors in our loop
analyses - If we're considering statements or basic blocks outside the
header and we're iterating backwards, as is the case for the
`vect_analyze_early_break_dependences' example, then it suffices to
check whether from one iteration to the next the loop to which the
current bb/ statement belongs to is still the loop we started our
analysis with, breaking out of the loop whenever we first enter the
child loop.  If the early break dependence is in the header, it
needn't be moved and, once we've covered the tail bb, we've exhausted
all relevant bb's in the loop.

gcc/ChangeLog:
        * tree-vect-data-refs.cc (vect_analyze_early_break_dependences):
        Ensure we don't jump between nested loops in analysis.
        * tree-vect-stmts.cc (vect_stmt_relevant_p): Likewise.
---
 gcc/tree-vect-data-refs.cc | 3 +++
 gcc/tree-vect-stmts.cc     | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
index e8cfb884c1d..afdb44aedda 100644
--- a/gcc/tree-vect-data-refs.cc
+++ b/gcc/tree-vect-data-refs.cc
@@ -835,6 +835,9 @@ vect_analyze_early_break_dependences (loop_vec_info 
loop_vinfo)
       /* All earlier blocks need dependence checking.  */
       check_deps = true;
       bb = single_pred (bb);
+
+      if (bb->loop_father != loop)
+       break;
     }
   while (1);
 
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 1620fc6cbcc..43c0639f3aa 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -428,7 +428,8 @@ vect_stmt_relevant_p (stmt_vec_info stmt_info, 
loop_vec_info loop_vinfo,
       && gimple_bb (stmt) == LOOP_VINFO_LOOP (loop_vinfo)->header
       && ((! VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info))
          && ! *live_p)
-         || STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def))
+         || STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
+      && (!loop->inner || gimple_bb (stmt)->loop_father == loop))
     {
       if (dump_enabled_p ())
        dump_printf_loc (MSG_NOTE, vect_location,
-- 
2.43.0

Reply via email to