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

24 lines
739 B
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=m68k -o - %s | FileCheck %s
@myvar = external thread_local global i32, 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: move.l %a0, %d0
; CHECK-NEXT: lea (_GLOBAL_OFFSET_TABLE_@GOTPCREL,%pc), %a0
; CHECK-NEXT: add.l (myvar@GOTTPOFF,%a0), %d0
; CHECK-NEXT: move.l %d0, %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)