https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109393
--- Comment #17 from ptomsich at gcc dot gnu.org --- In my view, we are compounding multiple discussions here: 1. A frontend "defect" (or: "Why the match.pd Change Is Correct") The C frontend's pointer_int_sum applies a premature distributive-law optimization when computing array subscripts. For a[j - 1] where the index expression is j + (-1), it distributes the sizeof(int) multiplication through the addition: a[j - 1] → *(a + (ulong)j * 4 + (-4)) // distributed form a[k] → *(a + (ulong)(j - 1) * 4) // factored form (k = j - 1) Richard identified this in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109393#c3: the premature distribution in pointer_int_sum produces two structurally different GIMPLE representations for the same address, and "this kind of stuff shouldn't be done by the frontends these days." The factored form (cast(X + C)) * S is the canonical GIMPLE form for array-index arithmetic. The match.pd pattern added by the PR109393 fix correctly re-factors the distributed form back to canonical: (A * B) + (-C) → (B - C/A) * A when C is a multiple of A This transforms (ulong)j * 4 + (-4) into ((ulong)j + (-1)) * 4, restoring the factored form. The patch is correct and should not be reverted — it compensates for a frontend deficiency that Richard explicitly called out. 2. The Residual Asymmetry (or: Why func1 and func2 differ..) The problem is that FRE can prove this equivalence in only one direction, depending on which form it encounters first. func2 fails because the statements appear in the opposite order of func1. 3. The x86 backend might not be entirely innocent? x86-64 has "[base + index*scale + displacement]" (SIB ... I had to look the term up!) encoding that handles all three components in a single instruction. The distributed form "a + j*4 + (-4)" maps directly. The factored form "a + (j - 1)*4" requires computing "j - 1" first. AArch64 does not have a "[base + index*scale + displacement]" addressing mode. This is the same cost as any alternative — the factored form is natural for AArch64. No regression. Looking at "ix86_legitimize_address" (I didn't expect that I'd ever have to poke around there), has logic for "PLUS(MULT, PLUS)", but not for "MULT(PLUS(reg, const), scale)". My guess is that adding some distrubution logic to "ix86_legitimize_address" (to handle "PLUS(base, MULT(PLUS(reg, const), scale))") So no, don't revert the fix. It is correct.
