summaryrefslogtreecommitdiff
path: root/lib/Target/AArch64/AArch64ISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AArch64/AArch64ISelLowering.cpp')
-rw-r--r--lib/Target/AArch64/AArch64ISelLowering.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp
index e2e472fa9f..071b432998 100644
--- a/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1863,7 +1863,7 @@ AArch64TargetLowering::LowerGlobalAddressELF(SDValue Op,
// TableGen doesn't have easy access to the CodeModel or RelocationModel, so
// we make that distinction here.
- // We support the static, small memory model for now.
+ // We support the small memory model for now.
assert(getTargetMachine().getCodeModel() == CodeModel::Small);
EVT PtrVT = getPointerTy();
@@ -1871,6 +1871,18 @@ AArch64TargetLowering::LowerGlobalAddressELF(SDValue Op,
const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
const GlobalValue *GV = GN->getGlobal();
unsigned Alignment = GV->getAlignment();
+ Reloc::Model RelocM = getTargetMachine().getRelocationModel();
+
+ if (GV->isWeakForLinker() && RelocM == Reloc::Static) {
+ // Weak symbols can't use ADRP/ADD pair since they should evaluate to
+ // zero when undefined. In PIC mode the GOT can take care of this, but in
+ // absolute mode we use a constant pool load.
+ return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
+ DAG.getConstantPool(GV, GN->getValueType(0)),
+ MachinePointerInfo::getConstantPool(),
+ /*isVolatile=*/ false, /*isNonTemporal=*/ true,
+ /*isInvariant=*/ true, 8);
+ }
if (Alignment == 0) {
const PointerType *GVPtrTy = cast<PointerType>(GV->getType());
@@ -1886,7 +1898,6 @@ AArch64TargetLowering::LowerGlobalAddressELF(SDValue Op,
}
unsigned char HiFixup, LoFixup;
- Reloc::Model RelocM = getTargetMachine().getRelocationModel();
bool UseGOT = Subtarget->GVIsIndirectSymbol(GV, RelocM);
if (UseGOT) {