[llvm] r174518 - Implement external weak (ELF) symbols on AArch64
Tim Northover
Tim.Northover at arm.com
Wed Feb 6 08:43:34 PST 2013
Author: tnorthover
Date: Wed Feb 6 10:43:33 2013
New Revision: 174518
URL: http://llvm.org/viewvc/llvm-project?rev=174518&view=rev
Log:
Implement external weak (ELF) symbols on AArch64
Weakly defined symbols should evaluate to 0 if they're undefined at
link-time. This is impossible to do with the usual address generation
patterns, so we should use a literal pool entry to materlialise the
address.
Added:
llvm/trunk/test/CodeGen/AArch64/extern-weak.ll
Modified:
llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=174518&r1=174517&r2=174518&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Wed Feb 6 10:43:33 2013
@@ -1863,7 +1863,7 @@ AArch64TargetLowering::LowerGlobalAddres
// 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::LowerGlobalAddres
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::LowerGlobalAddres
}
unsigned char HiFixup, LoFixup;
- Reloc::Model RelocM = getTargetMachine().getRelocationModel();
bool UseGOT = Subtarget->GVIsIndirectSymbol(GV, RelocM);
if (UseGOT) {
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=174518&r1=174517&r2=174518&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Wed Feb 6 10:43:33 2013
@@ -2409,8 +2409,10 @@ class A64I_LDRlitSimple<bits<2> opc, bit
"ldr\t$Rt, $Imm19", patterns, NoItinerary>;
let mayLoad = 1 in {
- def LDRw_lit : A64I_LDRlitSimple<0b00, 0b0, GPR32>;
- def LDRx_lit : A64I_LDRlitSimple<0b01, 0b0, GPR64>;
+ def LDRw_lit : A64I_LDRlitSimple<0b00, 0b0, GPR32,
+ [(set (i32 GPR32:$Rt), (load constpool:$Imm19))]>;
+ def LDRx_lit : A64I_LDRlitSimple<0b01, 0b0, GPR64,
+ [(set (i64 GPR64:$Rt), (load constpool:$Imm19))]>;
}
def LDRs_lit : A64I_LDRlitSimple<0b00, 0b1, FPR32,
Added: llvm/trunk/test/CodeGen/AArch64/extern-weak.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/extern-weak.ll?rev=174518&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/extern-weak.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/extern-weak.ll Wed Feb 6 10:43:33 2013
@@ -0,0 +1,13 @@
+; RUN: llc -mtriple=aarch64-none-linux-gnu -o - < %s | FileCheck %s
+
+declare extern_weak i32 @var()
+
+define i32()* @foo() {
+; The usual ADRP/ADD pair can't be used for a weak reference because it must
+; evaluate to 0 if the symbol is undefined. We use a litpool entry.
+ ret i32()* @var
+; CHECK: ldr x0, .LCPI0_0
+
+; CHECK: .LCPI0_0:
+; CHECK-NEXT: .xword var
+}
More information about the llvm-commits
mailing list