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_0
If 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.)