Hi! Packed attribute/pragma isn't the only way to cause types to be less than naturally aligned. Aligned attribute can do the same thing (and, for non-aggregates, packed attribute is ignored and thus aligned(X) is the only way to express it). The alignment_reachable targhook takes (or should take) care of other reasons why peeling the loop doesn't always lead into naturally aligned vectors (e.g. when for the types ADJUST_FIELD_ALIGN sometimes lowers alignment and thus pointers to the fields aren't naturally aligned, eventhough TYPE_ALIGN says it should).
Bootstrapped/regtested on x86_64-linux and i686-linux, approved by richi in bugzilla/on IRC, committed to trunk/4.6. 2011-04-08 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/48377 * tree-vect-data-refs.c (vector_alignment_reachable_p): Set is_packed to true even for types with smaller TYPE_ALIGN than TYPE_SIZE. * gcc.dg/vect/pr48377.c: New test. --- gcc/tree-vect-data-refs.c.jj 2011-03-18 09:43:50.000000000 +0100 +++ gcc/tree-vect-data-refs.c 2011-04-08 11:05:22.305451288 +0200 @@ -1143,6 +1143,9 @@ vector_alignment_reachable_p (struct dat if (ba) is_packed = contains_packed_reference (ba); + 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)) --- gcc/testsuite/gcc.dg/vect/pr48377.c.jj 2011-04-08 10:55:31.317420241 +0200 +++ gcc/testsuite/gcc.dg/vect/pr48377.c 2011-04-08 10:59:31.203402115 +0200 @@ -0,0 +1,25 @@ +/* PR tree-optimization/48377 */ +/* { dg-do run } */ + +typedef unsigned int U __attribute__((__aligned__ (1), __may_alias__)); + +__attribute__((noinline, noclone)) unsigned int +foo (const char *s, int len) +{ + const U *p = (const U *) s; + unsigned int f = len / sizeof (unsigned int), hash = len, i; + + for (i = 0; i < f; ++i) + hash += *p++; + return hash; +} + +char buf[64] __attribute__((aligned (32))); + +int +main (void) +{ + return foo (buf + 1, 26) != 26; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ Jakub