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.

Reply via email to