http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50716

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #4 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-10-14 
12:09:27 UTC ---
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.

Reply via email to