
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.
20 lines
606 B
LLVM
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)
|