https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63184
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Ok, so we can (and do) forward addresses like &a[_9] into plain dereferences, so lowering these addresses early is probably not a good idea. We could lower them as a very first thing in GIMPLE reassoc but that would still need to apply transforms like (i + 1) * 4 -> i*4 + 4 to be most effective (though that generally applies). Otherwise I can't see an easy place to hook in simplification of i.0_3 = i; _4 = i.0_3 * 4; _5 = (sizetype) _4; _6 = _5 + 4; _7 = &a[1] + _6; _9 = i.0_3 + 2; _10 = &a[_9]; if (_7 != _10) which is what we get for the first testcase after initial scalar cleanups. SLSR helps somewhat in some cases but it's run very late. We could detect address comparisons with the same base and use the affine combination machinery to simplify them though. From somewhere. tree-ssa-forwprop.c probably. Simplify them to _7 - _10 CMP 0 (if the addresses have the same base object at least that should cancel). We canonicalize (base p+ off1) p+ off2 to base p+ (off1 + off2) which should help here as well. We could also only "fold" away the base object from the chain (not using the affine machinery). match-and-simplify doesn't help here because the replacement involves an expression created by get_inner_reference (well, a manual transform would work here, of course).