https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65103
Bug ID: 65103
Summary: [i386] GOTOFF relocation is not propagated into
address expression
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: enkovich.gnu at gmail dot com
In PIC code there are multiple cases when GOTOFF relocation is put into
register and then used in address expression instead of using relocation
directly in address expression. Here is an example:
>cat test.c
typedef struct S
{
int a;
int sum;
int delta;
} S;
S gs;
int global_opt (int max)
{
while (gs.sum < max)
gs.sum += gs.delta;
return gs.a;
}
>gcc test.c -m32 -O2 -fPIE -S
>cat test.s
...
pushl %esi
leal gs@GOTOFF, %esi
pushl %ebx
call __x86.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
movl 12(%esp), %edx
movl 4(%esi,%ebx), %eax
cmpl %eax, %edx
jle .L4
movl 8(%esi,%ebx), %ecx
.L3:
addl %ecx, %eax
cmpl %eax, %edx
jg .L3
movl %eax, 4(%esi,%ebx)
.L4:
movl gs@GOTOFF(%ebx), %eax
popl %ebx
popl %esi
ret
A separate instruction to get gs@GOTOFF is generated in expand. Later fwprop
propagates this constant only into memory references with zero offset and leave
register usage in all others.
Used compiler:
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --enable-languages=c,c++,fortran
--disable-bootstrap --prefix=/export/users/ienkovic/ --disable-libsanitizer
Thread model: posix
gcc version 5.0.0 20150217 (experimental) (GCC)