]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorRichard Biener <rguenther@suse.de>
Mon, 26 Nov 2018 13:31:21 +0000 (13:31 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 26 Nov 2018 13:31:21 +0000 (13:31 +0000)
2018-11-26  Richard Biener  <rguenther@suse.de>

Backport from mainline
2018-10-15  Richard Biener  <rguenther@suse.de>

PR middle-end/87610
* tree-ssa-structalias.c (struct vls_data): Add escaped_p member.
(visit_loadstore): When a used restrict tag escaped verify that
the points-to solution of "other" pointers do not include
escaped.
(compute_dependence_clique): If a used restrict tag escaped
communicated that down to visit_loadstore.

* gcc.dg/torture/restrict-6.c: New testcase.

2018-10-25  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87665
PR tree-optimization/87745
* tree-vectorizer.h (get_earlier_stmt): Remove.
(get_later_stmt): Pick up UID from the original non-pattern stmt.

* gfortran.dg/20181025-1.f: New testcase.

2018-10-24  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87665
* tree-vect-data-refs.c (vect_preserves_scalar_order_p): Adjust
to reflect reality.

* gcc.dg/torture/pr87665.c: New testcase.

From-SVN: r266460

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr87665.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/restrict-6.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/20181025-1.f [new file with mode: 0644]
gcc/tree-ssa-structalias.c
gcc/tree-vect-data-refs.c
gcc/tree-vectorizer.h

index d057e26662bf6238562492b43f53532a4fe5c1da..77d3a77c399b33446dc9291d4bbd64bac02bb477 100644 (file)
@@ -1,3 +1,29 @@
+2018-11-26  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2018-10-15  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/87610
+       * tree-ssa-structalias.c (struct vls_data): Add escaped_p member.
+       (visit_loadstore): When a used restrict tag escaped verify that
+       the points-to solution of "other" pointers do not include
+       escaped.
+       (compute_dependence_clique): If a used restrict tag escaped
+       communicated that down to visit_loadstore.
+
+       2018-10-25  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87665
+       PR tree-optimization/87745
+       * tree-vectorizer.h (get_earlier_stmt): Remove.
+       (get_later_stmt): Pick up UID from the original non-pattern stmt.
+
+       2018-10-24  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87665
+       * tree-vect-data-refs.c (vect_preserves_scalar_order_p): Adjust
+       to reflect reality.
+
 2018-11-26  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index b5a5d8654c1ac5cae44774847ce059b294ef7877..c260750ffe4d3719b8347ca7e4d5468eb2a1bbc0 100644 (file)
@@ -1,3 +1,22 @@
+2018-11-26  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2018-10-15  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/87610
+       * gcc.dg/torture/restrict-6.c: New testcase.
+
+       2018-10-25  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87665
+       PR tree-optimization/87745
+       * gfortran.dg/20181025-1.f: New testcase.
+
+       2018-10-24  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87665
+       * gcc.dg/torture/pr87665.c: New testcase.
+
 2018-11-26  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/torture/pr87665.c b/gcc/testsuite/gcc.dg/torture/pr87665.c
new file mode 100644 (file)
index 0000000..6f5e968
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+
+struct X { long x; long y; };
+
+struct X a[1024], b[1024];
+
+void foo ()
+{
+  for (int i = 0; i < 1024; ++i)
+    {
+      long tem = a[i].x;
+      a[i].x = 0;
+      b[i].x = tem;
+      b[i].y = a[i].y;
+    }
+}
+
+int main()
+{
+  for (int i = 0; i < 1024; ++i)
+    a[i].x = i;
+  foo ();
+  for (int i = 0; i < 1024; ++i)
+    if (b[i].x != i)
+      __builtin_abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/restrict-6.c b/gcc/testsuite/gcc.dg/torture/restrict-6.c
new file mode 100644 (file)
index 0000000..9fe12a6
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+void __attribute__((noinline)) g(int **a, int *b)
+{
+  *a = b;
+}
+
+int foo(int * restrict p, int *q)
+{
+  g(&q, p);
+  *p = 1;
+  *q = 2;
+  return *p + *q;
+}
+
+int main()
+{
+  int x, y;
+  if (foo(&x, &y) != 4)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/20181025-1.f b/gcc/testsuite/gfortran.dg/20181025-1.f
new file mode 100644 (file)
index 0000000..1acbd72
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! { dg-options "-Ofast" }
+! { dg-additional-options "-mavx2" { target { x86_64-*-* i?86-*-* } } }
+      SUBROUTINE FOO(EF3,CA,ZA,NATA,IC4,NFRGPT)
+      IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+      PARAMETER (MXATM=500)
+      COMMON DE(3,MXATM)
+      DIMENSION CA(3,NATA)
+      DIMENSION ZA(NATA)
+      DIMENSION EF3(3,NFRGPT)
+      DO II = 1,NATA
+         XII = XJ - CA(1,II)
+         YII = YJ - CA(2,II)
+         ZII = ZJ - CA(3,II)
+         RJII = SQRT(XII*XII + YII*YII + ZII*ZII)
+         R3 = RJII*RJII*RJII
+         IF (IC4.EQ.0) THEN
+            DE(1,II) = DE(1,II) - S2*ZA(II)*XII/R3
+            DE(2,II) = DE(2,II) - S2*ZA(II)*YII/R3
+            DE(3,II) = DE(3,II) - S2*ZA(II)*ZII/R3
+         ELSE 
+            EF3(1,IC4+II) = EF3(1,IC4+II) - S2*ZA(II)*XII/R3
+            EF3(2,IC4+II) = EF3(2,IC4+II) - S2*ZA(II)*YII/R3
+            EF3(3,IC4+II) = EF3(3,IC4+II) - S2*ZA(II)*ZII/R3
+         END IF
+      END DO
+      RETURN
+      END           
index 33ad80efe3c4c33f158807cc79c945663b315341..b5a5f0f54d195fc3759b222a2ea7e8d94da06a74 100644 (file)
@@ -7274,6 +7274,7 @@ delete_points_to_sets (void)
 struct vls_data
 {
   unsigned short clique;
+  bool escaped_p;
   bitmap rvars;
 };
 
@@ -7285,6 +7286,7 @@ visit_loadstore (gimple *, tree base, tree ref, void *data)
 {
   unsigned short clique = ((vls_data *) data)->clique;
   bitmap rvars = ((vls_data *) data)->rvars;
+  bool escaped_p = ((vls_data *) data)->escaped_p;
   if (TREE_CODE (base) == MEM_REF
       || TREE_CODE (base) == TARGET_MEM_REF)
     {
@@ -7305,7 +7307,8 @@ visit_loadstore (gimple *, tree base, tree ref, void *data)
            return false;
 
          vi = get_varinfo (find (vi->id));
-         if (bitmap_intersect_p (rvars, vi->solution))
+         if (bitmap_intersect_p (rvars, vi->solution)
+             || (escaped_p && bitmap_bit_p (vi->solution, escaped_id)))
            return false;
        }
 
@@ -7382,6 +7385,7 @@ compute_dependence_clique (void)
   unsigned short clique = 0;
   unsigned short last_ruid = 0;
   bitmap rvars = BITMAP_ALLOC (NULL);
+  bool escaped_p = false;
   for (unsigned i = 0; i < num_ssa_names; ++i)
     {
       tree ptr = ssa_name (i);
@@ -7451,7 +7455,12 @@ compute_dependence_clique (void)
                                                 last_ruid);
            }
          if (used)
-           bitmap_set_bit (rvars, restrict_var->id);
+           {
+             bitmap_set_bit (rvars, restrict_var->id);
+             varinfo_t escaped = get_varinfo (find (escaped_id));
+             if (bitmap_bit_p (escaped->solution, restrict_var->id))
+               escaped_p = true;
+           }
        }
     }
 
@@ -7464,7 +7473,7 @@ compute_dependence_clique (void)
         parameters) we can't restrict scoping properly thus the following
         is too aggressive there.  For now we have excluded those globals from
         getting into the MR_DEPENDENCE machinery.  */
-      vls_data data = { clique, rvars };
+      vls_data data = { clique, escaped_p, rvars };
       basic_block bb;
       FOR_EACH_BB_FN (bb, cfun)
        for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
index f0e97060d7b802b37dacc0aaf3249a3ba0f2fb5d..9c32d9a90eec872e1cb3d242ce4e3366a088f22f 100644 (file)
@@ -195,6 +195,45 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
 }
 
 
+/* Return true if we know that the order of vectorized STMT_A and
+   vectorized STMT_B will be the same as the order of STMT_A and STMT_B.
+   At least one of the statements is a write.  */
+
+static bool
+vect_preserves_scalar_order_p (gimple *stmt_a, gimple *stmt_b)
+{
+  stmt_vec_info stmtinfo_a = vinfo_for_stmt (stmt_a);
+  stmt_vec_info stmtinfo_b = vinfo_for_stmt (stmt_b);
+
+  /* Single statements are always kept in their original order.  */
+  if (!STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
+      && !STMT_VINFO_GROUPED_ACCESS (stmtinfo_b))
+    return true;
+
+  /* STMT_A and STMT_B belong to overlapping groups.  All loads in a
+     group are emitted at the position of the last scalar load and all
+     stores in a group are emitted at the position of the last scalar store.
+     Compute that position and check whether the resulting order matches
+     the current one.  */
+  gimple *last_a = GROUP_FIRST_ELEMENT (stmtinfo_a);
+  if (last_a)
+    for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_a)); s;
+        s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+      last_a = get_later_stmt (last_a, s);
+  else
+    last_a = stmt_a;
+  gimple *last_b = GROUP_FIRST_ELEMENT (stmtinfo_b);
+  if (last_b)
+    for (gimple *s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (last_b)); s;
+        s = GROUP_NEXT_ELEMENT (vinfo_for_stmt (s)))
+      last_b = get_later_stmt (last_b, s);
+  else
+    last_b = stmt_b;
+  return ((get_later_stmt (last_a, last_b) == last_a)
+         == (get_later_stmt (stmt_a, stmt_b) == stmt_a));
+}
+
+
 /* Function vect_analyze_data_ref_dependence.
 
    Return TRUE if there (might) exist a dependence between a memory-reference
@@ -378,20 +417,13 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
                ... = a[i];
                a[i+1] = ...;
             where loads from the group interleave with the store.  */
-         if (STMT_VINFO_GROUPED_ACCESS (stmtinfo_a)
-             || STMT_VINFO_GROUPED_ACCESS (stmtinfo_b))
+         if (!vect_preserves_scalar_order_p (DR_STMT (dra), DR_STMT (drb)))
            {
-             gimple *earlier_stmt;
-             earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
-             if (DR_IS_WRITE
-                   (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
-               {
-                 if (dump_enabled_p ())
-                   dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                                    "READ_WRITE dependence in interleaving."
-                                    "\n");
-                 return true;
-               }
+             if (dump_enabled_p ())
+               dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                                "READ_WRITE dependence in interleaving."
+                                "\n");
+             return true;
            }
 
          unsigned int step_prec = TYPE_PRECISION (TREE_TYPE (DR_STEP (dra)));
index 12bb904abee5c0811576ad808bee451c6463a7fd..276289bd8cf9bb17e9f8abd8c77db67a40980867 100644 (file)
@@ -833,32 +833,22 @@ set_vinfo_for_stmt (gimple *stmt, stmt_vec_info info)
     }
 }
 
-/* Return the earlier statement between STMT1 and STMT2.  */
+/* Return TRUE if a statement represented by STMT_INFO is a part of a
+   pattern.  */
 
-static inline gimple *
-get_earlier_stmt (gimple *stmt1, gimple *stmt2)
+static inline bool
+is_pattern_stmt_p (stmt_vec_info stmt_info)
 {
-  unsigned int uid1, uid2;
-
-  if (stmt1 == NULL)
-    return stmt2;
-
-  if (stmt2 == NULL)
-    return stmt1;
-
-  uid1 = gimple_uid (stmt1);
-  uid2 = gimple_uid (stmt2);
-
-  if (uid1 == 0 || uid2 == 0)
-    return NULL;
+  gimple *related_stmt;
+  stmt_vec_info related_stmt_info;
 
-  gcc_checking_assert (uid1 <= stmt_vec_info_vec.length ()
-                      && uid2 <= stmt_vec_info_vec.length ());
+  related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
+  if (related_stmt
+      && (related_stmt_info = vinfo_for_stmt (related_stmt))
+      && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
+    return true;
 
-  if (uid1 < uid2)
-    return stmt1;
-  else
-    return stmt2;
+  return false;
 }
 
 /* Return the later statement between STMT1 and STMT2.  */
@@ -874,8 +864,12 @@ get_later_stmt (gimple *stmt1, gimple *stmt2)
   if (stmt2 == NULL)
     return stmt1;
 
-  uid1 = gimple_uid (stmt1);
-  uid2 = gimple_uid (stmt2);
+  stmt_vec_info stmt_info1 = vinfo_for_stmt (stmt1);
+  stmt_vec_info stmt_info2 = vinfo_for_stmt (stmt2);
+  uid1 = gimple_uid (is_pattern_stmt_p (stmt_info1)
+                    ? STMT_VINFO_RELATED_STMT (stmt_info1) : stmt1);
+  uid2 = gimple_uid (is_pattern_stmt_p (stmt_info2)
+                    ? STMT_VINFO_RELATED_STMT (stmt_info2) : stmt2);
 
   if (uid1 == 0 || uid2 == 0)
     return NULL;
@@ -889,24 +883,6 @@ get_later_stmt (gimple *stmt1, gimple *stmt2)
     return stmt2;
 }
 
-/* Return TRUE if a statement represented by STMT_INFO is a part of a
-   pattern.  */
-
-static inline bool
-is_pattern_stmt_p (stmt_vec_info stmt_info)
-{
-  gimple *related_stmt;
-  stmt_vec_info related_stmt_info;
-
-  related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
-  if (related_stmt
-      && (related_stmt_info = vinfo_for_stmt (related_stmt))
-      && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
-    return true;
-
-  return false;
-}
-
 /* Return true if BB is a loop header.  */
 
 static inline bool