mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[ARM] [Windows] Use COFF stubs for calls to extern_weak functions
As the extern_weak target might be missing, resolving to the absolute address zero, we can't use the normal direct PC-relative branch instructions (as that would result in relocations out of range). Instead check the shouldAssumeDSOLocal method and load the address from a COFF stub. This matches what was done for X86 in 6bf108d77a3c. Differential Revision: https://reviews.llvm.org/D71720
This commit is contained in:
parent
8452e4df8a
commit
407a0e7a75
@ -2356,12 +2356,14 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
} else if (Subtarget->isTargetCOFF()) {
|
||||
assert(Subtarget->isTargetWindows() &&
|
||||
"Windows is the only supported COFF target");
|
||||
unsigned TargetFlags = GV->hasDLLImportStorageClass()
|
||||
? ARMII::MO_DLLIMPORT
|
||||
: ARMII::MO_NO_FLAG;
|
||||
unsigned TargetFlags = ARMII::MO_NO_FLAG;
|
||||
if (GV->hasDLLImportStorageClass())
|
||||
TargetFlags = ARMII::MO_DLLIMPORT;
|
||||
else if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
|
||||
TargetFlags = ARMII::MO_COFFSTUB;
|
||||
Callee = DAG.getTargetGlobalAddress(GV, dl, PtrVt, /*offset=*/0,
|
||||
TargetFlags);
|
||||
if (GV->hasDLLImportStorageClass())
|
||||
if (TargetFlags & (ARMII::MO_DLLIMPORT | ARMII::MO_COFFSTUB))
|
||||
Callee =
|
||||
DAG.getLoad(PtrVt, dl, DAG.getEntryNode(),
|
||||
DAG.getNode(ARMISD::Wrapper, dl, PtrVt, Callee),
|
||||
|
@ -5,14 +5,17 @@
|
||||
declare i8* @f()
|
||||
declare extern_weak i8* @g(i8*)
|
||||
|
||||
; weak symbol resolution occurs statically in PE/COFF, ensure that we permit
|
||||
; tail calls on weak externals when targeting a COFF environment.
|
||||
define void @test() {
|
||||
%call = tail call i8* @f()
|
||||
%call1 = tail call i8* @g(i8* %call)
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-COFF: b g
|
||||
; CHECK-COFF: movw r0, :lower16:.refptr.g
|
||||
; CHECK-COFF: movt r0, :upper16:.refptr.g
|
||||
; CHECK-COFF: ldr r4, [r0]
|
||||
; CHECK-COFF: mov r1, r4
|
||||
; CHECK-COFF: bx r1
|
||||
|
||||
; CHECK-OTHER: bl {{_?}}g
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user