i386: Use SBB more [PR94650]
commit9decd08b7b153a593a0b61e4f5373cb9574a1973
authorUros Bizjak <ubizjak@gmail.com>
Mon, 4 May 2020 16:53:30 +0000 (4 18:53 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Mon, 4 May 2020 16:53:30 +0000 (4 18:53 +0200)
treec5af1ef9949c4a9658cb54802bf8c280a9bcecc3
parent97268c374a348a60c53366a4bee67626c840e4a1
i386: Use SBB more [PR94650]

When returning 0 or -1, "SBB reg,reg" instruction that borrows carry
flag can be used.  Carry flag can be generated by converting compare
with zero to a LTU compare with one, so e.g.

return -(x == 0)

generates:

        cmpq    $1, %rdi
        sbbq    %rax, %rax

instead of:

        xorl    %eax, %eax
        testq   %rdi, %rdi
        sete    %al
        negq    %rax

A similar conversion can be used for

return -(x != 0)

where NEG insn can be used instead of compare.  According to x86 ISA,
NEG insn sets carry flag when the source operand is != 0, resulting in:

        negq    %rdi
        sbbq    %rax, %rax

The conversion avoids partial register stall with SETcc instructions.

PR target/94795
* config/i386/i386.md (*neg<mode>_ccc): New insn pattern.
(EQ compare->LTU compare splitter): New splitter.
(NE compare->NEG splitter): Ditto.

testsuite/ChangeLog:

PR target/94795
* gcc.target/i386/pr94795-1.c: New test.
* gcc.target/i386/pr94795-2.c: New test.
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr94795-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr94795-2.c [new file with mode: 0644]