re PR tree-optimization/53970 (-ftree-vectorization does not handle well unaligned...
authorRichard Guenther <rguenther@suse.de>
Wed, 18 Jul 2012 10:46:05 +0000 (10:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 18 Jul 2012 10:46:05 +0000 (10:46 +0000)
2012-07-18  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/53970
* tree.h (contains_packed_reference): Remove.
* expr.c (contains_packed_reference): Likewise.
* tree-vect-data-refs.c (not_size_aligned): New function.
(vector_alignment_reachable_p): Use it.
(vect_supportable_dr_alignment): Likewise.

* g++.dg/torture/pr53970.C: New testcase.

From-SVN: r189609

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr53970.C [new file with mode: 0644]
gcc/tree-vect-data-refs.c
gcc/tree.h

index ff479659b3580bcf29e66f73d6839aa99eabc3c2..eda5fb6293914c05636229ec63d20e327d108b0f 100644 (file)
@@ -1,3 +1,12 @@
+2012-07-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/53970
+       * tree.h (contains_packed_reference): Remove.
+       * expr.c (contains_packed_reference): Likewise.
+       * tree-vect-data-refs.c (not_size_aligned): New function.
+       (vector_alignment_reachable_p): Use it.
+       (vect_supportable_dr_alignment): Likewise.
+
 2012-07-18  Richard Guenther  <rguenther@suse.de>
 
        * tree.h (get_object_or_type_alignment): Remove.
index 880e1bcab5a68294aaff3ef091dac8f9f5a4ab11..3ba57432460b2b9f8a561e55962d05f39c80bd69 100644 (file)
@@ -6709,47 +6709,6 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
   return exp;
 }
 
-/* Given an expression EXP that may be a COMPONENT_REF, an ARRAY_REF or an
-   ARRAY_RANGE_REF, look for whether EXP or any nested component-refs within
-   EXP is marked as PACKED.  */
-
-bool
-contains_packed_reference (const_tree exp)
-{
-  bool packed_p = false;
-
-  while (1)
-    {
-      switch (TREE_CODE (exp))
-       {
-       case COMPONENT_REF:
-         {
-           tree field = TREE_OPERAND (exp, 1);
-           packed_p = DECL_PACKED (field)
-                      || TYPE_PACKED (TREE_TYPE (field))
-                      || TYPE_PACKED (TREE_TYPE (exp));
-           if (packed_p)
-             goto done;
-         }
-         break;
-
-       case BIT_FIELD_REF:
-       case ARRAY_REF:
-       case ARRAY_RANGE_REF:
-       case REALPART_EXPR:
-       case IMAGPART_EXPR:
-       case VIEW_CONVERT_EXPR:
-         break;
-
-       default:
-         goto done;
-       }
-      exp = TREE_OPERAND (exp, 0);
-    }
- done:
-  return packed_p;
-}
-
 /* Return a tree of sizetype representing the size, in bytes, of the element
    of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
 
index 5477d4102e0b823eb237b2deef6cda5739ecad50..b046c68a3d3ab83ff048b990610b4510b7d68fe3 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-18  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/53970
+       * g++.dg/torture/pr53970.C: New testcase.
+
 2012-07-18  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/38621
diff --git a/gcc/testsuite/g++.dg/torture/pr53970.C b/gcc/testsuite/g++.dg/torture/pr53970.C
new file mode 100644 (file)
index 0000000..53cbc1f
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-do run }
+
+#pragma pack(1)
+struct mystruct {
+    char c;
+    unsigned long l[1024];
+};
+#pragma pack()
+
+int main(int argc, char **argv)
+{
+  mystruct *a = new mystruct;
+  unsigned long i;
+  for (i = 0; i < 1024; ++i)
+    a->l[i] = 0xdeadbeaf;
+  return 0;
+}
index dd0752e69cf4307f59d6b603b1591c25e868dcc7..147fa902cd644e33d82971e0b303bcb3f3853814 100644 (file)
@@ -1131,6 +1131,18 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
   return true;
 }
 
+/* Given an memory reference EXP return whether its alignment is less
+   than its size.  */
+
+static bool
+not_size_aligned (tree exp)
+{
+  if (!host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1))
+    return true;
+
+  return (tree_low_cst (TYPE_SIZE (TREE_TYPE (exp)), 1)
+         > get_object_alignment (exp));
+}
 
 /* Function vector_alignment_reachable_p
 
@@ -1184,12 +1196,8 @@ vector_alignment_reachable_p (struct data_reference *dr)
 
   if (!known_alignment_for_access_p (dr))
     {
-      tree type = (TREE_TYPE (DR_REF (dr)));
-      bool is_packed = contains_packed_reference (DR_REF (dr));
-
-      if (compare_tree_int (TYPE_SIZE (type), TYPE_ALIGN (type)) > 0)
-       is_packed = true;
-
+      tree type = TREE_TYPE (DR_REF (dr));
+      bool is_packed = not_size_aligned (DR_REF (dr));
       if (vect_print_dump_info (REPORT_DETAILS))
        fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed);
       if (targetm.vectorize.vector_alignment_reachable (type, is_packed))
@@ -4863,7 +4871,7 @@ vect_supportable_dr_alignment (struct data_reference *dr,
            return dr_explicit_realign_optimized;
        }
       if (!known_alignment_for_access_p (dr))
-       is_packed = contains_packed_reference (DR_REF (dr));
+       is_packed = not_size_aligned (DR_REF (dr));
 
       if (targetm.vectorize.
          support_vector_misalignment (mode, type,
@@ -4877,7 +4885,7 @@ vect_supportable_dr_alignment (struct data_reference *dr,
       tree type = (TREE_TYPE (DR_REF (dr)));
 
       if (!known_alignment_for_access_p (dr))
-       is_packed = contains_packed_reference (DR_REF (dr));
+       is_packed = not_size_aligned (DR_REF (dr));
 
      if (targetm.vectorize.
          support_vector_misalignment (mode, type,
index 2261f2d089c0bdc11a97d2268cc8b246d18d1ea5..62d66456e3255ffec409d0c75705cf931b921ebc 100644 (file)
@@ -5068,12 +5068,6 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
                                 tree *, enum machine_mode *, int *, int *,
                                 bool);
 
-/* Given an expression EXP that may be a COMPONENT_REF, an ARRAY_REF or an
-   ARRAY_RANGE_REF, look for whether EXP or any nested component-refs within
-   EXP is marked as PACKED.  */
-
-extern bool contains_packed_reference (const_tree exp);
-
 /* Return a tree of sizetype representing the size, in bytes, of the element
    of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */