http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48702
--- Comment #7 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-04-21 12:32:04 UTC --- IVOPTs generates ivtmp.25_24 = (long unsigned int) &array; array.26_26 = (long unsigned int) &array; D.2769_27 = array.26_26 + 0x0fffffffffffffff0; <bb 3>: # ans_21 = PHI <ans_16(4), 0(2)> # ivtmp.25_20 = PHI <ivtmp.25_19(4), ivtmp.25_24(2)> D.2741_10 = ans_21 * 2; D.2767_25 = (void *) ivtmp.25_20; D.2737_15 = MEM[(int *)D.2767_25 + 12B]; ans_16 = D.2741_10 + D.2737_15; ivtmp.25_19 = ivtmp.25_20 - 4; if (ivtmp.25_19 != D.2769_27) goto <bb 4>; else goto <bb 5>; <bb 4>: goto <bb 3>; thus, the addition of the constant offset does not happen in a separate unsigned long computation but is (of course) folded into the (TARGET_)MEM_REF. What now exposes this kind of bugs is that we 1) prefer to generate MEM_REFs instead of equivalent TARGET_MEM_REFs, 2) do not completely give up on TARGET_MEM_REFs in alias analysis. I am somewhat sympathetic to treating indirect (TARGET_)MEM_REFs as opaque, only looking at the final pointer that is dereferenced, not at the pieces of the address computation. We'd retain the case where two such derefrences differ only in a constant offset. I don't think that any pass interprets the address computation that is implicit in a memory refrence in any way at the moment.