https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107627

--- Comment #8 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:2c089640279614e34b8712bfb318a9d4fc8ac8fe

commit r13-4435-g2c089640279614e34b8712bfb318a9d4fc8ac8fe
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Dec 1 09:29:23 2022 +0100

    i386: Improve *concat<mode><dwi>3_{1,2,3,4} patterns [PR107627]

    On the first testcase we've regressed since 12 at -O2:
    -       movq    8(%rsi), %rax
    -       movq    %rdi, %r8
    -       movq    (%rsi), %rdi
    +       movq    (%rsi), %rax
    +       movq    8(%rsi), %r8
            movl    %edx, %ecx
    -       shrdq   %rdi, %rax
    -       movq    %rax, (%r8)
    +       xorl    %r9d, %r9d
    +       movq    %rax, %rdx
    +       xorl    %eax, %eax
    +       orq     %r8, %rax
    +       orq     %r9, %rdx
    +       shrdq   %rdx, %rax
    +       movq    %rax, (%rdi)
    On the second testcase we've emitted such terrible code
    with the useless xors and ors for a long time.
    For PR91681 the *concat<mode><dwi>3_{1,2,3,4} patterns have been added
    but they allow just register inputs and register or memory offsettable
    output.
    The following patch fixes this by allowing also memory inputs on those
    patterns, because the pattern is then split to 0-2 emit_move_insns or
    one xchg and those can handle loads from memory too just fine.
    So that we don't narrow memory loads (source has 128-bit (or for ia32
    64-bit) load and we would make 64-bit (or for ia32 32-bit) load out of it),
    register_operand -> nonmemory_operand change is done only for operands
    in zero_extend arguments.  o <- m, m or o <- m, r or o <- r, m alternatives
    aren't used, we'd lack registers to perform the moves.  But what is
    in addition to the current ro <- r, r supported are r <- m, r and r <- r, m
    (in that case we just need to be careful about corner cases, see what
    emit_move_insn we'd call and if we wouldn't clobber registers used in m's
    address before loading - split_double_concat handles that now) and
    &r <- m, m (in that case I think the early clobber is the easiest
solution).

    The first testcase then on 12 -> patched trunk at -O2 changes:
    -       movq    8(%rsi), %rax
    -       movq    %rdi, %r8
    -       movq    (%rsi), %rdi
    +       movq    8(%rsi), %r9
    +       movq    (%rsi), %r10
            movl    %edx, %ecx
    -       shrdq   %rdi, %rax
    -       movq    %rax, (%r8)
    +       movq    %r9, %rax
    +       shrdq   %r10, %rax
    +       movq    %rax, (%rdi)
    so same amount of instructions and second testcase 12 -> patched trunk
    at -O2 -m32:
    -       pushl   %edi
    -       xorl    %edi, %edi
            pushl   %esi
    -       movl    16(%esp), %esi
    +       pushl   %ebx
    +       movl    16(%esp), %eax
            movl    20(%esp), %ecx
    -       movl    (%esi), %eax
    -       movl    4(%esi), %esi
    -       movl    %eax, %edx
    -       movl    $0, %eax
    -       orl     %edi, %edx
    -       orl     %esi, %eax
    -       shrdl   %edx, %eax
            movl    12(%esp), %edx
    +       movl    4(%eax), %ebx
    +       movl    (%eax), %esi
    +       movl    %ebx, %eax
    +       shrdl   %esi, %eax
            movl    %eax, (%edx)
    +       popl    %ebx
            popl    %esi
    -       popl    %edi

    BTW, I wonder if we couldn't add additional patterns which would catch
    the case where one of the operands is constant and how does this interact
    with the stv pass in 32-bit mode where I think stv is right after combine,
    so if we match these patterns, perhaps it would be nice to handle them
    in stv (unless they are handled there already).

    2022-12-01  Jakub Jelinek  <ja...@redhat.com>

            PR target/107627
            * config/i386/i386.md (*concat<mode><dwi>3_1,
*concat<mode><dwi>3_2):
            For operands which are zero_extend arguments allow memory if
            output operand is a register.
            (*concat<mode><dwi>3_3, *concat<mode><dwi>3_4): Likewise.  If
            both input operands are memory, use early clobber on output
operand.
            * config/i386/i386-expand.cc (split_double_concat): Deal with
corner
            cases where one input is memory and the other is not and the
address
            of the memory input uses a register we'd overwrite before loading
            the memory into a register.

            * gcc.target/i386/pr107627-1.c: New test.
            * gcc.target/i386/pr107627-2.c: New test.

Reply via email to