This fixes the get_earlier_stmt call in vect_preserves_scalar_order_p to
properly use non-pattern stmts.  I came along this when reworking
how we change DR_STMT during vectorization - this mimics the way
the SLP code uses get_later_stmt.

I've added asserts into get_earlier/later_stmt to make sure we're never
called on pattern stmts (those can end up with UIDs out-of-order).

Not sure if we actually run into this (not in the testsuite),
but it'll be a separate rev to bisect to and backport if required.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

>From 823c9b42d8910c78413e087acf3bb5546b04b300 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguent...@suse.de>
Date: Tue, 29 May 2018 13:44:18 +0200
Subject: [PATCH] fix-dr-order-checks

        * tree-vect-data-refs.c (vect_preserves_scalar_order_p): Make
        sure to use non-pattern stmts for get_earlier_stmt arguments.
        * tree-vectorizer.h (get_earlier_stmt): Assert we do not get
        called on pattern stmts.
        (get_later_stmt): Likewise.

diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index f46eb467da6..9255c53189d 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -212,6 +212,10 @@ vect_preserves_scalar_order_p (gimple *stmt_a, gimple 
*stmt_b)
      (but could happen later) while reads will happen no later than their
      current position (but could happen earlier).  Reordering is therefore
      only possible if the first access is a write.  */
+  if (is_pattern_stmt_p (stmtinfo_a))
+    stmt_a = STMT_VINFO_RELATED_STMT (stmtinfo_a);
+  if (is_pattern_stmt_p (stmtinfo_b))
+    stmt_b = STMT_VINFO_RELATED_STMT (stmtinfo_b);
   gimple *earlier_stmt = get_earlier_stmt (stmt_a, stmt_b);
   return !DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt)));
 }
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index f7646349b65..25d0aae8eaa 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1068,8 +1068,12 @@ get_earlier_stmt (gimple *stmt1, gimple *stmt2)
   if (uid1 == 0 || uid2 == 0)
     return NULL;
 
-  gcc_checking_assert (uid1 <= stmt_vec_info_vec->length ()
-                      && uid2 <= stmt_vec_info_vec->length ());
+  gcc_assert (uid1 <= stmt_vec_info_vec->length ()
+             && uid2 <= stmt_vec_info_vec->length ());
+  gcc_checking_assert ((STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt1))
+                       || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt1)))
+                      && (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt2))
+                          || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt 
(stmt2))));
 
   if (uid1 < uid2)
     return stmt1;
@@ -1096,8 +1100,12 @@ get_later_stmt (gimple *stmt1, gimple *stmt2)
   if (uid1 == 0 || uid2 == 0)
     return NULL;
 
-  gcc_assert (uid1 <= stmt_vec_info_vec->length ());
-  gcc_assert (uid2 <= stmt_vec_info_vec->length ());
+  gcc_assert (uid1 <= stmt_vec_info_vec->length ()
+             && uid2 <= stmt_vec_info_vec->length ());
+  gcc_checking_assert ((STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt1))
+                       || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt1)))
+                      && (STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (stmt2))
+                          || !STMT_VINFO_RELATED_STMT (vinfo_for_stmt 
(stmt2))));
 
   if (uid1 > uid2)
     return stmt1;

Reply via email to