This patch is addressing two issues:
- https://bugs.llvm.org/show_bug.cgi?id=47124. A weak function containing a jump table causes a linker warning on Darwin because the entries (LBB - lJTI) refer back to the function and can't be overridden.
- The AArch64 "small" code model that we default to requires that all statically allocated code and data is within a 4GB window, somewhere in memory. Unfortunately our jump table entries are 32-bit signed constants which only have a 2GB reach, and they're located in a different section (to allow for things like execute-only memory).
Without that second issue I'd prefer to silence the linker warning somehow, and without the first I'd be tempted to let sleeping dogs lie, but together I think they make a compelling enough case to change how we do jump tables. Currently we emit something like
adrp x0, LJTI0_0@PAGE
add x0, x0, LJTI0_0@PAGEOFF
ldrsw x1, [x0, x2, lsl #2]
add x0, x0, x1
br x0
[...]
LJTI0_0:
.word LBB0_0 - LJTI0_0If we can no longer use LJTI0_0 as the base we need something within the function that has to be materialized separately. So this changes the sequence to be
adrp x0, LJTI0_0@PAGE
add x0, x0, LJTI0_0@PAGEOFF
Ltmp0:
adr x1, Ltmp0
ldrsw x2, [x0, x2, lsl #2]
add x1, x1, x2, lsl #2
br x1
[...]
LJTI0_0:
.word (LBB0_0 - Ltmp0)>>2
For 32-bit, we sign-extend? I guess this is assuming a function can't be larger than 2GB? (I think you could avoid that assumption by using the compression infrastructure for 32-bit words.)