https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70359
--- Comment #24 from rguenther at suse dot de <rguenther at suse dot de> --- > OTOH, the following changes things quite a bit on arm: > > < p_22 = p_19 + 4294967295; > < *p_22 = 45; > --- > > p_22 = p_8 + 4294967294; > > MEM[(char *)p_19 + 4294967295B] = 45; > > For context, we are using p_8 which was the previous iteration's value for p_8 > and then subtracting 2 to return p correctly. What the heck? > > <bb 2> [local count: 118111601]: > _1 = ABS_EXPR <i_12(D)>; > ui_13 = (unsigned int) _1; > len.0_2 = (sizetype) len_14(D); > _3 = len.0_2 + 4294967295; > p_16 = buf_15(D) + _3; > *p_16 = 0; > > <bb 3> [local count: 1073741825]: > # ui_7 = PHI <ui_13(2), ui_21(3)> > # p_8 = PHI <p_16(2), p_19(3)> > _4 = ui_7 % 10; > _5 = (char) _4; > p_19 = p_8 + 4294967295; > _6 = _5 + 48; > MEM[base: p_19, offset: 0B] = _6; > ui_21 = ui_7 / 10; > if (ui_7 > 9) > goto <bb 3>; [89.00%] > else > goto <bb 4>; [11.00%] > > <bb 4> [local count: 118111601]: > if (i_12(D) < 0) > goto <bb 5>; [41.00%] > else > goto <bb 6>; [59.00%] > > <bb 5> [local count: 48425756]: > p_22 = p_8 + 4294967294; > MEM[(char *)p_19 + 4294967295B] = 45; > > <bb 6> [local count: 118111601]: > # p_9 = PHI <p_22(5), p_19(4)> > return p_9; forwprop aggressively canonicalizes memory references by forwarding all constant address adjustments into its constant offset part. What usually makes things complicated in the end is when for an IV we get overlapping life-ranges for the before and after value because that inhibits coalescing. Is this what happens here? We do have some code trying to rectify IV-related stuff for coalescing, maybe that can be enhanced to handle these kind of cases... I fear that in the end somehow exposing autoinc/dec on GIMPLE might be the only way to truly fix and maintain good code...