https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71347
--- Comment #2 from amker at gcc dot gnu.org --- Thanks for reporting this. The dump after IVOPT now is: <bb 3>: # prephitmp_21 = PHI <pretmp_20(4), powmult_2(2)> # prephitmp_23 = PHI <pretmp_22(4), powmult_2(2)> # ivtmp.17_16 = PHI <ivtmp.17_9(4), ivtmp.17_24(2)> _6 = prephitmp_21 * prephitmp_23; _4 = (void *) ivtmp.17_16; MEM[base: _4, offset: 0B] = _6; ivtmp.17_9 = ivtmp.17_16 + 8; if (ivtmp.17_9 != _26) goto <bb 4>; else goto <bb 5>; <bb 4>: _5 = (void *) ivtmp.17_9; pretmp_20 = MEM[base: _5, offset: 4294967288B]; pretmp_22 = X[1]; goto <bb 3>; That patch skips computing cost for sub iv_uses in a group: Group 0: Type: ADDRESS Use 0.0: At stmt: X[i_18] = _6; At pos: X[i_18] IV struct: Type: double * Base: (double *) (&X + 16) Step: 8 Object: (void *) &X Biv: N Overflowness wrto loop niter: Overflow Use 0.1: At stmt: pretmp_20 = X[_15]; At pos: X[_15] IV struct: Type: double * Base: (double *) (&X + 16) Step: 8 Object: (void *) &X Biv: N Overflowness wrto loop niter: Overflow Though use 0.0/0.1 have same {base, step}, but there are in different program point, so if iv_cand is increased before use 0.0, the first use is transformed into: MEM[var_before, 0], and use 0.1 will be transformed into: MEM[var_after, -8]. Now the two memory reference have different expressions, though access to the same object. Afterwards, DOM failed to CSE them. It is hard to decide which sub iv_use we should compute the cost, and which one we can skip computing the cost. Maybe I should revert this part of code which was introduced to save a small amount of compilation time.