]> git.ipfire.org Git - thirdparty/gcc.git/commit
i386: Fix addcarry/subborrow issues [PR117860]
authorUros Bizjak <ubizjak@gmail.com>
Thu, 5 Dec 2024 16:02:46 +0000 (17:02 +0100)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 5 Dec 2024 16:13:55 +0000 (17:13 +0100)
commitb3cb0c3302a7c16e661a08c15c897c8f7bbb5d23
tree64d702d9e830d4f297c7938fe07daced3441e81a
parenta92b2be97f369ae4c6e1cdcbb7a45525994afaad
i386: Fix addcarry/subborrow issues [PR117860]

Fix several things to enable combine to handle addcarry/subborrow patterns:

- Fix wrong canonical form of addcarry<mode> insn and friends. For
commutative operand (PLUS RTX) binary operand (LTU) takes precedence before
unary operand (ZERO_EXTEND).

- Swap operands of GTU comparison to canonicalize addcarry/subborrow
comparison. Again, the canonical form of the compare is PLUS RTX before
ZERO_EXTEND RTX. GTU comparison is not a carry flag comparison, so we have
to swap operands in x86_canonicalize_comparison to a non-canonical form
to use LTU comparison.

- Return correct compare mode (CCCmode) for addcarry/subborrow pattern
from ix86_cc_mode, so combine is able to emit required compare mode for
combined insn.

- Add *subborrow<mode>_1 pattern having const_scalar_int_operand predicate.
Here, canonicalization of SUB (op1, const) RTX to PLUS (op1, -const) requires
negation of constant operand when ckecking operands.

With the above changes, combine is able to create *addcarry_1/*subborrow_1
pattern with immediate operand for the testcase in the PR:

SomeAddFunc:
        addq    %rcx, %rsi      # 10    [c=4 l=3]  adddi3_cc_overflow_1/0
        movq    %rdi, %rax      # 33    [c=4 l=3]  *movdi_internal/3
        adcq    $5, %rdx        # 19    [c=4 l=4]  *addcarrydi_1/0
        movq    %rsi, (%rdi)    # 23    [c=4 l=3]  *movdi_internal/5
        movq    %rdx, 8(%rdi)   # 24    [c=4 l=4]  *movdi_internal/5
        setc    %dl     # 39    [c=4 l=3]  *setcc_qi
        movzbl  %dl, %edx       # 40    [c=4 l=3]  zero_extendqidi2/0
        movq    %rdx, 16(%rdi)  # 26    [c=4 l=4]  *movdi_internal/5
        ret             # 43    [c=0 l=1]  simple_return_internal

SomeSubFunc:
        subq    %rcx, %rsi      # 10    [c=4 l=3]  *subdi_3/0
        movq    %rdi, %rax      # 42    [c=4 l=3]  *movdi_internal/3
        sbbq    $17, %rdx       # 19    [c=4 l=4]  *subborrowdi_1/0
        movq    %rsi, (%rdi)    # 33    [c=4 l=3]  *movdi_internal/5
        sbbq    %rcx, %rcx      # 29    [c=8 l=3]  *x86_movdicc_0_m1_neg
        movq    %rdx, 8(%rdi)   # 34    [c=4 l=4]  *movdi_internal/5
        movq    %rcx, 16(%rdi)  # 35    [c=4 l=4]  *movdi_internal/5
        ret             # 51    [c=0 l=1]  simple_return_internal

PR target/117860

gcc/ChangeLog:

* config/i386/i386.cc (ix86_canonicalize_comparison): Swap
operands of GTU comparison to canonicalize addcarry/subborrow
comparison.
(ix86_cc_mode): Return CCCmode for the comparison of
addcarry/subborrow pattern.
* config/i386/i386.md (addcarry<mode>): Swap operands of
PLUS RTX to make it canonical.
(*addcarry<mode>_1): Ditto.
(addcarry peephole2s): Update RTXes for addcarry<mode>_1 change.
(*add<dwi>3_doubleword_cc_overflow_1): Ditto.
(*subborrow<mode>_1): New insn pattern.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr117860.c: New test.
gcc/config/i386/i386.cc
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr117860.c [new file with mode: 0644]