Peter Lafreniere ebbc5de7db
[M68k] Correctly emit non-pic relocations (#89863)
The m68k backend will always emit external calls (including libcalls)
with
PC-relative PLT relocations, even when in non-pic mode or -fno-plt is
used.

This is unexpected, as other function calls are emitted with absolute
addressing, and a static code modes suggests that there is no PLT. It
also
leads to a miscompilation where the call instruction emitted expects an
immediate address, while the relocation emitted for that instruction is
PC-relative.

This miscompilation can even be seen in the default C function in
godbolt:
https://godbolt.org/z/zEoazovzo

Fix the issue by classifying external function references based upon the
pic
mode. This triggers a change in the static code model, making it more in
line
with the expected behaviour and allowing use of this backend in more
bare-metal
situations where a PLT does not exist.

The change avoids the issue where we emit a PLT32 relocation for an
absolute
call, and makes libcalls and other external calls use absolute
addressing modes
when a static code model is desired.

Further work should be done in instruction lowering and validation to
ensure
that miscompilations of the same type don't occur.
2024-05-03 23:14:56 +08:00

20 lines
606 B
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=m68k -o - %s | FileCheck %s
@myvar = internal thread_local global i32 2, align 4
define dso_local ptr @get_addr() nounwind {
; CHECK-LABEL: get_addr:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: suba.l #4, %sp
; CHECK-NEXT: jsr __m68k_read_tp
; CHECK-NEXT: lea (myvar@TPOFF,%a0), %a0
; CHECK-NEXT: adda.l #4, %sp
; CHECK-NEXT: rts
entry:
%0 = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @myvar)
ret ptr %0
}
declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)