https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93002
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The originally reported issue is fixed. Though, the following testcase shows we could do better: void foo (void); void bar (unsigned); unsigned f1 (unsigned x) { if (--x == -1U) foo (); return x; } unsigned f2 (unsigned x) { if (++x == 0) foo (); return x; } unsigned f3 (unsigned x) { if (--x == 0x7fffffffU) foo (); return x; } unsigned f4 (unsigned x) { if (++x == 0x80000000U) foo (); return x; } void f5 (unsigned *x) { if (--*x == -1U) foo (); } void f6 (unsigned *x) { if (++*x == 0) foo (); } void f7 (unsigned *x) { if (--*x == 0x7fffffffU) foo (); } void f8 (unsigned *x) { if (++*x == 0x80000000U) foo (); } void f9 (unsigned x) { if (--x != -1U) bar (x); } void f10 (unsigned x) { if (++x != 0) bar (x); } void f11 (unsigned x) { if (--x != 0x7fffffffU) bar (x); } void f12 (unsigned x) { if (++x != 0x80000000U) bar (x); } void f13 (unsigned x) { do bar (x); while (--x != -1U); } void f14 (unsigned x) { do bar (x); while (++x != 0); } void f15 (unsigned x) { do bar (x); while (--x != 0x7fffffffU); } void f16 (unsigned x) { do bar (x); while (++x != 0x80000000U); } The committed patch improved f13, f2/f6/f10/f14 were already handled well in the past. The memory decrement + test for -1 could be optimized by a different peephole2 (catch the load + decrement + store + comparison), and the cases with INT_MIN/INT_MAX could be optimized into inc/dec with jno/jo instead of jne/je after it. f1/f3/f4/f9/f11/f12 can't be dealt with a peephole2, already RA decides to put it into different registers and uses lea which doesn't affect the flags. In f1/f3/f4 the different register is actually needed, although we could e.g. inc/dec + jnc etc. followed by mov, in f9/f11/f12 it would be better to use the same register.