https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127864
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
unsigned foo (unsigned x) { return x > 1 ? x : 1; }
unsigned bar (unsigned x) { return x ? x : 1; }
unsigned baz (unsigned x) { return x + (x == 0); }
The third function expands to adc, others use cmovne (on x86_64).
On aarch64 -O2, the first two result in cmp w0, 0 + csinc w0, w0, wzr, ne
and the last one to cmp w0, 0 + cinc w0, w0, eq.
On powerpc the last one is shorter, on powerpc64 same size but first two
contain conditional branches. On riscv the last one is a win insn count wise
too.
That said,
_4 = MAX_EXPR <x_2(D), 1>;
is shorter than
_1 = x_3(D) == 0;
_2 = (unsigned int) _1;
_4 = _2 + x_3(D);
so I think we should instead canonicalize the latter to the former and either
unconditionally or conditionally depending on rtx costs attempt to expand
unsigned MAX_EXPR with 1 as x + (x == 0).