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.