https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70424

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2016-03-29
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
   Target Milestone|---                         |4.9.4
     Ever confirmed|0                           |1

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
This is because of

get_object_alignment_2 (...)
...
      known_alignment
        = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos);
...
      /* When EXP is an actual memory reference then we can use
         TYPE_ALIGN of a pointer indirection to derive alignment.
         Do so only if get_pointer_alignment_1 did not reveal absolute
         alignment knowledge and if using that alignment would
         improve the situation.  */
      if (!addr_p && !known_alignment
          && TYPE_ALIGN (TREE_TYPE (exp)) > align)
        align = TYPE_ALIGN (TREE_TYPE (exp));

and get_pointer_alignment_1 returning true as we hit

  else if (TREE_CODE (exp) == SSA_NAME
           && POINTER_TYPE_P (TREE_TYPE (exp)))
    {
      unsigned int ptr_align, ptr_misalign;
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);

      if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign))
        {
          *bitposp = ptr_misalign * BITS_PER_UNIT;
          *alignp = ptr_align * BITS_PER_UNIT;
          /* Make sure to return a sensible alignment when the multiplication
             by BITS_PER_UNIT overflowed.  */
          if (*alignp == 0)
            *alignp = 1u << (HOST_BITS_PER_INT - 1);
          /* We cannot really tell whether this result is an approximation.  */
          return true;

thus whenever flow-sensitive propagation computed an alignment value.

I agree (I think we have duplicates for this bug) that this is somewhat
odd behavior and we can unconditionally factor in TYPE_ALIGN.

Note that the current behavior was implemented to catch

char a[4];

int main()
{
  return *(int *)a;
}

where GCC _knowns_ that 'a' is not aligned according to 'int'.  

So the appropriate fix might be to just do

Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c      (revision 234453)
+++ gcc/builtins.c      (working copy)
@@ -463,7 +463,7 @@ get_pointer_alignment_1 (tree exp, unsig
          if (*alignp == 0)
            *alignp = 1u << (HOST_BITS_PER_INT - 1);
          /* We cannot really tell whether this result is an approximation.  */
-         return true;
+         return false;
        }
       else
        {

but it will likely pessimize ipa-prop because it cares for the return value
for some reason.  So we'd need sth like

Index: gcc/ipa-prop.c
===================================================================
--- gcc/ipa-prop.c      (revision 234453)
+++ gcc/ipa-prop.c      (working copy)
@@ -1640,10 +1640,10 @@ ipa_compute_jump_functions_for_edge (str
          unsigned align;

          if (get_pointer_alignment_1 (arg, &align, &hwi_bitpos)
+             && align > BITS_PER_UNIT
              && align % BITS_PER_UNIT == 0
              && hwi_bitpos % BITS_PER_UNIT == 0)
            {
-             gcc_checking_assert (align != 0);
              jfunc->alignment.known = true;
              jfunc->alignment.align = align / BITS_PER_UNIT;
              jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT;

as well.

Reply via email to