On Mon, May 30, 2022 at 7:50 PM Roger Sayle <ro...@nextmovesoftware.com> wrote:
>
>
> This patch resolves PR rtl-optimization/101617 where we should generate
> the exact same code for (X ? -1 : 1) as we do for ((X ? -1 : 0) | 1).
> The cause of the current difference on x86_64 is actually in
> ix86_expand_int_movcc that doesn't know that negl;sbbl can be used
> to create a -1/0 result depending on whether the input is zero/nonzero.
>
> So for Andrew Pinski's test case:
>
> int f1(int i)
> {
>   return i ? -1 : 1;
> }
>
> GCC currently generates:
>
> f1:     cmpl    $1, %edi
>         sbbl    %eax, %eax      // x ? 0 : -1
>         andl    $2, %eax        // x ? 0 : 2
>         subl    $1, %eax        // x ? -1 : 1
>         ret
>
> but with the attached patch, now generates:
>
> f1:     negl    %edi
>         sbbl    %eax, %eax      // x ? -1 : 0
>         orl     $1, %eax        // x ? -1 : 1
>         ret
>
> To implement this I needed to add two expanders to i386.md to generate
> the required instructions (in both SImode and DImode) matching the
> pre-existing define_insns of the same name.
>
> This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> and make -k check, both with and without --target_board=unix{-m32},
> with no new failures.  Ok for mainline?
>
>
> 2022-05-30  Roger Sayle  <ro...@nextmovesoftware.com>
>
> gcc/ChangeLog
>         PR rtl-optimization/101617
>         * config/i386/i386-expand.cc (ix86_expand_int_movcc): Add a
>         special case (indicated by negate_cc_compare_p) to generate a
>         -1/0 mask using neg;sbb.
>         * config/i386/i386.md (x86_neg<mode>_ccc): New define_expand
>         to generate an *x86_neg<mode>_ccc instruction.
>         (x86_mov<mode>cc_0_m1_neg): Likewise, a new define_expand to
>         generate a *x86_mov<mode>cc_0_m1_neg instruction.
>
> gcc/testsuite/ChangeLog
>         PR rtl-optimization/101617
>         * gcc.target/i386/pr101617.c: New test case.

LGTM.

Thanks,
Uros.

Reply via email to