[PATCH] D71720: [ARM] [Windows] Use COFF stubs for calls to extern_weak functions

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 19 11:13:05 PST 2019


mstorsjo created this revision.
mstorsjo added reviewers: rnk, smeenai.
Herald added subscribers: hiraditya, kristof.beyls.
Herald added a project: LLVM.

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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71720

Files:
  llvm/lib/Target/ARM/ARMISelLowering.cpp
  llvm/test/CodeGen/ARM/tail-call-weak.ll


Index: llvm/test/CodeGen/ARM/tail-call-weak.ll
===================================================================
--- llvm/test/CodeGen/ARM/tail-call-weak.ll
+++ llvm/test/CodeGen/ARM/tail-call-weak.ll
@@ -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
 
Index: llvm/lib/Target/ARM/ARMISelLowering.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2348,12 +2348,14 @@
       } 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),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D71720.234747.patch
Type: text/x-patch
Size: 1958 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191219/9f7a4552/attachment.bin>


More information about the llvm-commits mailing list