Since 4.9 we're quite "strict" about "less alignment" that we might
possibly know about when seeing dereferences.  But that implementation
is quite inconsistent as treating 1-byte alignment as never
"possibly known" (unless we see a decl).

So the following patch makes us only consider the case where we
see a decl directly as "known" and override the alignment used
on the access.

This makes

int f(long a)
{
    int *p=(int*)(a<<1);
    return *p;
}

use alignof(int) for the access *p rather than 2-byte alignment
as derived from the left-shift by 1.

This drops a few "legacy" cases where a pointer derived from a decl
is no longer detected.  But if we figure we still need to care about
this we should add a more proper machinery to detect it.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied but
not planning to backport.

Richard.

2016-03-29  Richard Biener  <rguent...@suse.de>

        PR middle-end/70424
        * ipa-prop.c (ipa_compute_jump_functions_for_edge): Always
        use alignment returned by get_pointer_alignment_1 if it is
        bigger than BITS_PER_UNIT.
        * builtins.c (get_pointer_alignment_1): Do not return true
        for alignment extracted from SSA info.

Index: gcc/ipa-prop.c
===================================================================
*** gcc/ipa-prop.c      (revision 234453)
--- gcc/ipa-prop.c      (working copy)
*************** ipa_compute_jump_functions_for_edge (str
*** 1639,1649 ****
          unsigned HOST_WIDE_INT hwi_bitpos;
          unsigned align;
  
!         if (get_pointer_alignment_1 (arg, &align, &hwi_bitpos)
              && 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;
--- 1639,1649 ----
          unsigned HOST_WIDE_INT hwi_bitpos;
          unsigned align;
  
!         get_pointer_alignment_1 (arg, &align, &hwi_bitpos);
!         if (align > BITS_PER_UNIT
              && align % BITS_PER_UNIT == 0
              && hwi_bitpos % BITS_PER_UNIT == 0)
            {
              jfunc->alignment.known = true;
              jfunc->alignment.align = align / BITS_PER_UNIT;
              jfunc->alignment.misalign = hwi_bitpos / BITS_PER_UNIT;
Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c      (revision 234453)
--- gcc/builtins.c      (working copy)
*************** get_pointer_alignment_1 (tree exp, unsig
*** 463,469 ****
          if (*alignp == 0)
            *alignp = 1u << (HOST_BITS_PER_INT - 1);
          /* We cannot really tell whether this result is an approximation.  */
!         return true;
        }
        else
        {
--- 463,469 ----
          if (*alignp == 0)
            *alignp = 1u << (HOST_BITS_PER_INT - 1);
          /* We cannot really tell whether this result is an approximation.  */
!         return false;
        }
        else
        {

Reply via email to