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%).