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; + }