]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/59374 (-ftree-slp-vectorize breaks unique_ptr's move constructor)
authorRichard Biener <rguenther@suse.de>
Thu, 5 Dec 2013 09:12:29 +0000 (09:12 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 5 Dec 2013 09:12:29 +0000 (09:12 +0000)
2013-12-05  Richard Biener  <rguenther@suse.de>

PR tree-optimization/59374
* tree-vect-data-refs.c (vect_slp_analyze_data_ref_dependence):
Commonize known and unknown dependence case fixing the allowed
read-write dependence case and dropping code that should not
matter.

* gcc.dg/torture/pr59374-1.c: New testcase.
* gcc.dg/torture/pr59374-2.c: Likewise.

From-SVN: r205694

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr59374-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr59374-2.c [new file with mode: 0644]
gcc/tree-vect-data-refs.c

index ffbd2948fde82c1f5aa218037cfa84d08c471fd7..ae5070481368013e3d7bdcc40925f9f3bb8c74e6 100644 (file)
@@ -1,3 +1,11 @@
+2013-12-05  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/59374
+       * tree-vect-data-refs.c (vect_slp_analyze_data_ref_dependence):
+       Commonize known and unknown dependence case fixing the allowed
+       read-write dependence case and dropping code that should not
+       matter.
+
 2013-12-05  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        * config/ia64/ia64.md (prologue_allocate_stack): Block auto-
index 07d071f6abc8d8b7f19e939bfe29812b58b34f59..12fbdcd49f601de2ef1400090fcecd2a64a181c4 100644 (file)
@@ -1,3 +1,9 @@
+2013-12-05  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/59374
+       * gcc.dg/torture/pr59374-1.c: New testcase.
+       * gcc.dg/torture/pr59374-2.c: Likewise.
+
 2013-12-05  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        * gcc.target/ia64/pr52731.c: New.
diff --git a/gcc/testsuite/gcc.dg/torture/pr59374-1.c b/gcc/testsuite/gcc.dg/torture/pr59374-1.c
new file mode 100644 (file)
index 0000000..6230ae9
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-slp-vectorize" } */
+
+extern void abort (void);
+
+static struct X { void *a; void *b; } a, b;
+
+void __attribute__((noinline))
+foo (void)
+{
+  void *tem = a.b;
+  a.b = (void *)0;
+  b.b = tem;
+  b.a = a.a;
+}
+
+int main()
+{
+  a.b = &a;
+  foo ();
+  if (b.b != &a)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr59374-2.c b/gcc/testsuite/gcc.dg/torture/pr59374-2.c
new file mode 100644 (file)
index 0000000..d791b98
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-slp-vectorize" } */
+
+extern void abort (void);
+
+static struct X { void *a; void *b; } a, b;
+static struct X *p;
+
+void __attribute__((noinline))
+foo (void)
+{
+  void *tem = a.b;
+  p->b = (void *)0;
+  b.b = tem;
+  b.a = a.a;
+}
+
+int main()
+{
+  p = &a;
+  a.b = &a;
+  foo ();
+  if (b.b != &a)
+    abort ();
+  return 0;
+}
index 87d151f836dfc2c11971c8955fb11fee7dd43777..741586067bfa053e9ab3701562b8fcfa3d44f99b 100644 (file)
@@ -497,31 +497,17 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
   /* Unknown data dependence.  */
   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
     {
-      gimple earlier_stmt;
-
-      if (dump_enabled_p ())
-        {
-          dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                           "can't determine dependence between ");
-          dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
-          dump_printf (MSG_MISSED_OPTIMIZATION,  " and ");
-          dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
+      if  (dump_enabled_p ())
+       {
+         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                          "can't determine dependence between ");
+         dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
+         dump_printf (MSG_MISSED_OPTIMIZATION,  " and ");
+         dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
          dump_printf (MSG_MISSED_OPTIMIZATION,  "\n");
-        }
-
-      /* We do not vectorize basic blocks with write-write dependencies.  */
-      if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))
-        return true;
-
-      /* Check that it's not a load-after-store dependence.  */
-      earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
-      if (DR_IS_WRITE (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
-        return true;
-
-      return false;
+       }
     }
-
-  if (dump_enabled_p ())
+  else if (dump_enabled_p ())
     {
       dump_printf_loc (MSG_NOTE, vect_location,
                       "determined dependence between ");
@@ -531,49 +517,23 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr)
       dump_printf (MSG_NOTE,  "\n");
     }
 
-  /* Do not vectorize basic blocks with write-write dependences.  */
+  /* We do not vectorize basic blocks with write-write dependencies.  */
   if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))
     return true;
 
-  /* Check dependence between DRA and DRB for basic block vectorization.
-     If the accesses share same bases and offsets, we can compare their initial
-     constant offsets to decide whether they differ or not.  In case of a read-
-     write dependence we check that the load is before the store to ensure that
-     vectorization will not change the order of the accesses.  */
-
-  HOST_WIDE_INT type_size_a, type_size_b, init_a, init_b;
-  gimple earlier_stmt;
-
-  /* Check that the data-refs have same bases and offsets.  If not, we can't
-     determine if they are dependent.  */
-  if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)
-      || !dr_equal_offsets_p (dra, drb))
-    return true;
-
-  /* Check the types.  */
-  type_size_a = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dra))));
-  type_size_b = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (drb))));
-
-  if (type_size_a != type_size_b
-      || !types_compatible_p (TREE_TYPE (DR_REF (dra)),
-                              TREE_TYPE (DR_REF (drb))))
-    return true;
-
-  init_a = TREE_INT_CST_LOW (DR_INIT (dra));
-  init_b = TREE_INT_CST_LOW (DR_INIT (drb));
-
-  /* Two different locations - no dependence.  */
-  if (init_a != init_b)
-    return false;
-
-  /* We have a read-write dependence.  Check that the load is before the store.
+  /* If we have a read-write dependence check that the load is before the store.
      When we vectorize basic blocks, vector load can be only before
      corresponding scalar load, and vector store can be only after its
      corresponding scalar store.  So the order of the acceses is preserved in
      case the load is before the store.  */
-  earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
+  gimple earlier_stmt = get_earlier_stmt (DR_STMT (dra), DR_STMT (drb));
   if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (earlier_stmt))))
-    return false;
+    {
+      /* That only holds for load-store pairs taking part in vectorization.  */
+      if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dra)))
+         && STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (drb))))
+       return false;
+    }
 
   return true;
 }