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 {