https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26731
--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #5) > In GCC 9 and above we get: > _2 = x_6(D) + 1; > _7 = (unsigned int) n_1; > _11 = _7 + 4294967295; > _15 = (int) _11; > _16 = n_1 > 0 ? _15 : 0; > x_3 = _2 + _16; > > Which is okish, the loop has been removed but the above should be able to > reduce further: > # RANGE [1, 2147483647] NONZERO 2147483647 > # n_1 = PHI <a_5(D)(3), 4(2)> > # RANGE [-2147483647, 2147483647] > _2 = x_6(D) + 1; > # RANGE [1, 2147483647] NONZERO 2147483647 > _7 = (unsigned int) n_1; > # RANGE [0, 2147483646] NONZERO 2147483647 > _11 = _7 + 4294967295; > # RANGE [0, 2147483646] NONZERO 2147483647 > _15 = (intD.9) _11; > # RANGE [0, 2147483646] NONZERO 2147483647 > _16 = n_1 > 0 ? _15 : 0; > x_3 = _2 + _16; > > The COND_EXPR should just converted into _15 but we don't ... > VRP should have done that .... That was fixed in GCC 13 by not have the COND_EXPR have the comparison in the first operand (I don't have the revision offhand). We now get at optimization: <bb 2> [local count: 118111600]: if (t_4(D) != 0) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 59055800]: if (a_5(D) > 0) goto <bb 4>; [66.92%] else goto <bb 5>; [33.08%] <bb 4> [local count: 105119324]: # n_1 = PHI <a_5(D)(3), 4(2)> _2 = x_6(D) + 1; _11 = (unsigned int) n_1; _15 = _11 + 4294967295; _16 = (int) _15; x_3 = _2 + _16; <bb 5> [local count: 118111600]: # x_13 = PHI <x_3(4), x_6(D)(3)> return x_13; }