PR rtl-optimization/101617: Use neg/sbb in ix86_expand_int_movcc.
authorRoger Sayle <roger@nextmovesoftware.com>
Mon, 30 May 2022 20:26:37 +0000 (21:26 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Mon, 30 May 2022 20:26:37 +0000 (21:26 +0100)
commitf1652e3343b1ec47035370801d9b9aca1f8b613f
tree2bc6a0e25cda63f5546b20cd0b2d13f969ff3438
parent2a12adfa8bd61e46538ebd97ae927d594843026a
PR rtl-optimization/101617: Use neg/sbb in ix86_expand_int_movcc.

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.

2022-05-30  Roger Sayle  <roger@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.
gcc/config/i386/i386-expand.cc
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr101617.c [new file with mode: 0644]