http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50716
--- Comment #5 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-10-14 12:10:52 UTC --- (In reply to comment #4) > It's because we do > > align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), get_object_alignment > (exp)); > > which discards the knowledge we have (exp is aligned to 4 bytes, > get_object_alignment returns 4). > > Which can be fixed for example by > > align = get_object_alignment_1 (exp, &misalign); > align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align); > if (misalign != 0) > align = (misalign & -misalign); > > so always honor an explicit knowledge about misalignment. Or less > aggressively, > > align = get_object_alignment_1 (exp, &misalign); > if (TYPE_ALIGN (TREE_TYPE (exp)) <= align) > { > if (misalign != 0) > align = (misalign & -misalign); > } > else > align = TYPE_ALIGN (TREE_TYPE (exp)); > > thus only when the base alignment is at least that of the types alignment. > Which means we'd treat a vector load from a misaligned int * pointer as > aligned, but from a misaligned vector int * pointer not - maybe too > surprising, > I'd definitely go with the first variant. Any idea which reasonable > case we'd miss here? Even *(vector int *)(int-ptr + 2) would be handled > as aligned, get_object_alignment_1 would return 32 (int aligned), the > misalign is truncated to the base alignment. One odd result is that with -O the code would "work" while with -O0 it would segfault (we don't know anything about the alignment at -O0 as CCP is not run).