http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46920

           Summary: suboptimal register allocation with local register
                    variables
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: ra
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: [email protected]
        ReportedBy: [email protected]
                CC: [email protected]
            Target: x86_64-pc-linux-gnu


Reduced testcase for x86_64:

int f(void **label, void **label2, char *xxx, char *yyy, char *zzz, char *ip0)
{
    register char *ip asm ("r12") = ip0;
    int arg;
    if (!*label) {
        *label = &&test;
        *label2 = &&test2;
        return;
    }
    arg = ip[1];
    goto **label;
test:
    ip += 2;
    if (*ip)
        ip += arg;
    arg = ip[1];
    goto **label2;
test2:
    return arg;
}

Assembly for the code between the labels:

    movq    %r12, %rcx          <<<
    leaq    2(%r12), %rdx       <<<
    cmpb    $0, 2(%rcx)         <<<
    movq    %rdx, %r12          <<<
    je    .L5
    cltq
    addq    %rax, %rdx          <<<
    movq    %rdx, %r12          <<<
.L5:
    movsbl    1(%rdx), %eax       <<<
    movq    (%rsi), %rdx
    jmp    *%rdx

The instructions marked with <<< are uselessly referencing a temporary
variable.

Optimal code could be:

    addq    $2, %r12            <<<
    cmpb    $0, (%r12)          <<<
    je    .L5
    cltq
    addq    %rax, %r12          <<<
.L5:
    movsbl    1(%r12), %eax       <<<
    movq    (%rsi), %rdx
    jmp    *%rdx

This is achieved without the register declaration, but the performance of the
full test case is much worse without it (around 25%).

Reply via email to