http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48702
--- Comment #5 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-04-21 11:05:09 UTC --- Before the patch: movq %rsp, %rdx leaq -16(%rsp), %rcx movl $0, %eax .L5: addl %eax, %eax addl 12(%rdx), %eax subq $4, %rdx cmpq %rcx, %rdx jne .L5 after the patch: movl $0, %edx movl $0, %eax .L5: addl %eax, %eax addl 12(%rsp,%rdx), %eax subq $4, %rdx cmpq $-16, %rdx jne .L5 not 100% clear which to prefer. Alternatively alias-analysis can be dumbed down, never exploiting knowledge of a constant offset added to a pointer before dereferencing it (thus, ignoring the constant offset operand in MEM_REFs and TARGET_MEM_REFs). FYI, the disambiguation that triggers is /* If only one reference is based on a variable, they cannot alias if the pointer access is beyond the extent of the variable access. (the pointer base cannot validly point to an offset less than zero of the variable). They also cannot alias if the pointer may not point to the decl. */ if ((TREE_CODE (base1) != TARGET_MEM_REF || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1))) && !ranges_overlap_p (MAX (0, offset1p), -1, offset2p, max_size2)) return false; thus, for "the pointer base cannod validly point to an offset less than zero" say that this only holds for ptr + constant offset, not ptr in isolation.