]> git.ipfire.org Git - thirdparty/gcc.git/commit
Improve ix86_expand_int_movcc to allow condition (mask) sharing.
authorRoger Sayle <roger@nextmovesoftware.com>
Tue, 3 Jan 2023 13:40:47 +0000 (13:40 +0000)
committerRoger Sayle <roger@nextmovesoftware.com>
Tue, 3 Jan 2023 13:40:47 +0000 (13:40 +0000)
commitd0558f420b2a5692fd38ac76ffa97ae6c1726ed9
tree7071eee51b1e31a16996154ed6392f4303afe06b
parentde59d8bd163a4b2e50ab566441ab49d7212c3356
Improve ix86_expand_int_movcc to allow condition (mask) sharing.

This patch modifies the way that ix86_expand_int_movcc generates RTL,
to allow the condition mask to be shared/reused between multiple
conditional move sequences.  Such redundancy is common when RTL
if-conversion transforms non-trivial basic blocks.

As a motivating example, consider the new test case:

int a, b, c, d;
int foo(int x)
{
    if (x == 0) {
        a = 3;
        b = 1;
        c = 4;
        d = 1;
    } else {
        a = 5;
        b = 9;
        c = 2;
        d = 7;
    }
    return x;
}

This is currently compiled, with -O2, to:

foo: cmpl $1, %edi
movl %edi, %eax
sbbl %edi, %edi
andl $-2, %edi
addl $5, %edi
cmpl $1, %eax
sbbl %esi, %esi
movl %edi, a(%rip)
andl $-8, %esi
addl $9, %esi
cmpl $1, %eax
sbbl %ecx, %ecx
movl %esi, b(%rip)
andl $2, %ecx
addl $2, %ecx
cmpl $1, %eax
sbbl %edx, %edx
movl %ecx, c(%rip)
andl $-6, %edx
addl $7, %edx
movl %edx, d(%rip)
ret

Notice that the if-then-else blocks have been if-converted into four
conditional move sequences/assignments, each consisting of cmpl, sbbl,
andl and addl.  However, as the conditions are the same, the cmpl and
sbbl instructions used to generate the mask could be shared by CSE.

This patch enables that so that we now generate:

foo:    cmpl    $1, %edi
        movl    %edi, %eax
        sbbl    %edx, %edx
        movl    %edx, %edi
        movl    %edx, %esi
        movl    %edx, %ecx
        andl    $-6, %edx
        andl    $-2, %edi
        andl    $-8, %esi
        andl    $2, %ecx
        addl    $7, %edx
        addl    $5, %edi
        addl    $9, %esi
        addl    $2, %ecx
        movl    %edx, d(%rip)
        movl    %edi, a(%rip)
        movl    %esi, b(%rip)
        movl    %ecx, c(%rip)
        ret

Notice, the code now contains only a single cmpl and a single sbbl,
with result being shared (via movl).

2023-01-03  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
* config/i386/i386-expand.cc (ix86_expand_int_movcc): Rewrite
RTL expansion to allow condition (mask) to be shared/reused,
by avoiding overwriting pseudos and adding REG_EQUAL notes.

gcc/testsuite/ChangeLog
* gcc.target/i386/cmov10.c: New test case.
gcc/config/i386/i386-expand.cc
gcc/testsuite/gcc.target/i386/cmov10.c [new file with mode: 0644]