re PR tree-optimization/53516 (Vectorization and memset recognition miscompile bitfie...
authorRichard Guenther <rguenther@suse.de>
Tue, 29 May 2012 14:40:16 +0000 (14:40 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 29 May 2012 14:40:16 +0000 (14:40 +0000)
2012-05-29  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/53516
* tree-data-ref.c (stmt_with_adjacent_zero_store_dr_p): Reject
bitfield accesses.
* tree-vect-data-refs.c (vect_analyze_data_refs): Likewise.

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

From-SVN: r187961

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

index f86c56bc5b262ad21a08401c5681ff974919f758..399da9304224cc2ae458e1241e2520ef5b47c2a7 100644 (file)
@@ -1,3 +1,10 @@
+2012-05-29  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/53516
+       * tree-data-ref.c (stmt_with_adjacent_zero_store_dr_p): Reject
+       bitfield accesses.
+       * tree-vect-data-refs.c (vect_analyze_data_refs): Likewise.
+
 2012-05-29  Joseph Myers  <joseph@codesourcery.com>
 
        * LANGUAGES: Fix typos.
index 1c1b28eeab97bfd16f4f6019b391d39bf3d366fb..56bb5abc88389d95abc27ab9e92db5600875d1e2 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-29  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/53516
+       * gcc.dg/torture/pr53516.c: New testcase.
+
 2012-05-29  Dodji Seketeli  <dodji@redhat.com>
 
        PR preprocessor/53229
diff --git a/gcc/testsuite/gcc.dg/torture/pr53516.c b/gcc/testsuite/gcc.dg/torture/pr53516.c
new file mode 100644 (file)
index 0000000..7f8094d
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-options "-ftree-vectorize -ftree-loop-distribute-patterns" } */
+
+extern void abort (void);
+
+struct Foo
+{
+  char a : 1;
+  char b : 7;
+};
+
+struct Foo x[256];
+int y[256];
+
+void __attribute__((noinline,noclone)) bar (int n)
+{
+  int i;
+  for (i = 0; i < n; ++i)
+    {
+      x[i].a = 0;
+      y[i] = 3;
+    }
+}
+
+int main()
+{
+  x[5].b = 7;
+  bar (256);
+  if (x[5].b != 7)
+    abort ();
+  return 0;
+}
index 90b6f70e4a912e7c177e08491ae6a3282c347b79..8a23efa36dc6e2556fdf523fbfac40887db0863b 100644 (file)
@@ -5255,26 +5255,33 @@ stores_from_loop (struct loop *loop, VEC (gimple, heap) **stmts)
 bool
 stmt_with_adjacent_zero_store_dr_p (gimple stmt)
 {
-  tree op0, op1;
+  tree lhs, rhs;
   bool res;
   struct data_reference *dr;
 
   if (!stmt
       || !gimple_vdef (stmt)
-      || !is_gimple_assign (stmt)
-      || !gimple_assign_single_p (stmt)
-      || !(op1 = gimple_assign_rhs1 (stmt))
-      || !(integer_zerop (op1) || real_zerop (op1)))
+      || !gimple_assign_single_p (stmt))
+    return false;
+
+  lhs = gimple_assign_lhs (stmt);
+  rhs = gimple_assign_rhs1 (stmt);
+
+  /* If this is a bitfield store bail out.  */
+  if (TREE_CODE (lhs) == COMPONENT_REF
+      && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
+    return false;
+
+  if (!(integer_zerop (rhs) || real_zerop (rhs)))
     return false;
 
   dr = XCNEW (struct data_reference);
-  op0 = gimple_assign_lhs (stmt);
 
   DR_STMT (dr) = stmt;
-  DR_REF (dr) = op0;
+  DR_REF (dr) = lhs;
 
   res = dr_analyze_innermost (dr, loop_containing_stmt (stmt))
-    && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (op0));
+    && stride_of_unit_type_p (DR_STEP (dr), TREE_TYPE (lhs));
 
   free_data_ref (dr);
   return res;
index a5ed0533db6ca3e03a4c2f91afa0a95c163c3676..e34f41a3f1f975459875dc63e1a6aa98f3f0408e 100644 (file)
@@ -2972,10 +2972,6 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
           return false;
         }
 
-      base = unshare_expr (DR_BASE_ADDRESS (dr));
-      offset = unshare_expr (DR_OFFSET (dr));
-      init = unshare_expr (DR_INIT (dr));
-
       if (stmt_can_throw_internal (stmt))
         {
           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
@@ -2997,6 +2993,32 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
           return false;
         }
 
+      if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF
+         && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1)))
+       {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+            {
+              fprintf (vect_dump, "not vectorized: statement is bitfield "
+                       "access ");
+              print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+            }
+
+          if (bb_vinfo)
+            {
+              STMT_VINFO_VECTORIZABLE (stmt_info) = false;
+              stop_bb_analysis = true;
+              continue;
+            }
+
+         if (gather)
+           free_data_ref (dr);
+          return false;
+       }
+
+      base = unshare_expr (DR_BASE_ADDRESS (dr));
+      offset = unshare_expr (DR_OFFSET (dr));
+      init = unshare_expr (DR_INIT (dr));
+
       if (is_gimple_call (stmt))
        {
          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))