With get_object_alignment and get_object_or_type_alignment fused
it is now easy to fix PR53970 and remove the bogus
contains_packed_reference function.  The vectorizer wants to know
whether the scalar access is aligned in a way that peeling
can eventually reach VF * scalar alignment (thus, vector alignment).
So, just ask that - whether the scalar access is aligned to at least
its size.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2012-07-18  Richard Guenther  <rguent...@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.

Index: gcc/tree.h
===================================================================
*** gcc/tree.h  (revision 189607)
--- gcc/tree.h  (working copy)
*************** extern tree get_inner_reference (tree, H
*** 5068,5079 ****
                                 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.  */
  
--- 5068,5073 ----
Index: gcc/expr.c
===================================================================
*** gcc/expr.c  (revision 189607)
--- gcc/expr.c  (working copy)
*************** get_inner_reference (tree exp, HOST_WIDE
*** 6709,6755 ****
    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.  */
  
--- 6709,6714 ----
Index: gcc/tree-vect-data-refs.c
===================================================================
*** gcc/tree-vect-data-refs.c   (revision 189607)
--- gcc/tree-vect-data-refs.c   (working copy)
*************** vect_verify_datarefs_alignment (loop_vec
*** 1131,1136 ****
--- 1131,1148 ----
    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
  
*************** vector_alignment_reachable_p (struct dat
*** 1184,1195 ****
  
    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;
! 
        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))
--- 1196,1203 ----
  
    if (!known_alignment_for_access_p (dr))
      {
!       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))
*************** vect_supportable_dr_alignment (struct da
*** 4863,4869 ****
            return dr_explicit_realign_optimized;
        }
        if (!known_alignment_for_access_p (dr))
!       is_packed = contains_packed_reference (DR_REF (dr));
  
        if (targetm.vectorize.
          support_vector_misalignment (mode, type,
--- 4871,4877 ----
            return dr_explicit_realign_optimized;
        }
        if (!known_alignment_for_access_p (dr))
!       is_packed = not_size_aligned (DR_REF (dr));
  
        if (targetm.vectorize.
          support_vector_misalignment (mode, type,
*************** vect_supportable_dr_alignment (struct da
*** 4877,4883 ****
        tree type = (TREE_TYPE (DR_REF (dr)));
  
        if (!known_alignment_for_access_p (dr))
!       is_packed = contains_packed_reference (DR_REF (dr));
  
       if (targetm.vectorize.
           support_vector_misalignment (mode, type,
--- 4885,4891 ----
        tree type = (TREE_TYPE (DR_REF (dr)));
  
        if (!known_alignment_for_access_p (dr))
!       is_packed = not_size_aligned (DR_REF (dr));
  
       if (targetm.vectorize.
           support_vector_misalignment (mode, type,
Index: gcc/testsuite/g++.dg/torture/pr53970.C
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/torture/pr53970.C      2012-07-16 14:30:04.831593896 
+0200
***************
*** 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;
+ }

Reply via email to