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

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
That was an intentional change, see the PR.
With -fPIC/-fPIE, when the switch isn't optimized into a table of values but
kept as a switch, it doesn't need runtime relocations on many targets.  Just
try to compile it, all the relocations e.g. on x86_64 are:
Relocation section '.rela.text' at offset 0x440 contains 12 entries:
    Offset             Info             Type               Symbol's Value 
Symbol's Name + Addend
0000000000000008  0000000600000002 R_X86_64_PC32          0000000000000000
.rodata - 4
0000000000000023  0000000900000002 R_X86_64_PC32          0000000000000000 .LC0
- 4
0000000000000033  0000000a00000002 R_X86_64_PC32          0000000000000007 .LC2
- 4
...
Relocation section '.rela.rodata' at offset 0x560 contains 16 entries:
    Offset             Info             Type               Symbol's Value 
Symbol's Name + Addend
0000000000000000  0000000200000002 R_X86_64_PC32          0000000000000000
.text + b0
0000000000000004  0000000200000002 R_X86_64_PC32          0000000000000000
.text + c4
0000000000000008  0000000200000002 R_X86_64_PC32          0000000000000000
.text + 38
...
everything resolved at link time.
While if the the switchconv happens (either older gcc before that commit or
e.g.
current clang):
Relocation section '.rela.text' at offset 0x2b8 contains 2 entries:
    Offset             Info             Type               Symbol's Value 
Symbol's Name + Addend
000000000000000b  0000000700000002 R_X86_64_PC32          0000000000000000
.data.rel.ro - 4
0000000000000017  0000000600000002 R_X86_64_PC32          000000000000003c
.L.str.10 - 4

Relocation section '.rela.data.rel.ro' at offset 0x2e8 contains 16 entries:
    Offset             Info             Type               Symbol's Value 
Symbol's Name + Addend
0000000000000000  0000000500000001 R_X86_64_64            0000000000000000
.rodata.str1.1 + 0
0000000000000008  0000000500000001 R_X86_64_64            0000000000000000
.rodata.str1.1 + 6
0000000000000010  0000000500000001 R_X86_64_64            0000000000000000
.rodata.str1.1 + c
0000000000000018  0000000500000001 R_X86_64_64            0000000000000000
.rodata.str1.1 + 12
0000000000000020  0000000500000001 R_X86_64_64            0000000000000000
.rodata.str1.1 + 18
...

So 16 runtime relocations.
Now, what GCC could do with a help of say a target hook would be for
-fPIC/-fpic when relocations would be needed consider doing something smarter.
E.g. on x86_64-linux with -fPIC, I think the code model requires that
.Lwhatever(%rip) works, so if we came up with some reasonable GIMPLE
representation (e.g. POINTER_DIFF_EXPR of the addresses and some label) of the
switch tables where in the end we'd emit something like:
.4byte .LC1 - .L12345
.4byte .LC2 - .L12345
.4byte .LC3 - .L12345
in the tables (not just no dynamic relocations, but also 50% size of the switch
table) and then in the code sign extend the loaded value and add .L12345, we
could optimize this nicely.

Reply via email to