fix an arm codegen bug (the same as PR4482 on ppc) where available_externally

symbols were not getting stubs.  While I'm at it, add a big testcase for
stub generation to make sure I don't break anything.

llvm-svn: 75737
This commit is contained in:
Chris Lattner 2009-07-15 04:12:33 +00:00
parent 53fe736214
commit 55452c2bea
3 changed files with 73 additions and 7 deletions

View File

@ -935,8 +935,7 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
GlobalValue *GV = G->getGlobal();
isDirect = true;
bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage());
bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
bool isStub = (isExt && Subtarget->isTargetDarwin()) &&
getTargetMachine().getRelocationModel() != Reloc::Static;
isARMFunc = !Subtarget->isThumb() || isStub;
@ -1179,7 +1178,7 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
// Get the Thread Pointer
SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
if (GV->isDeclaration()){
if (GV->isDeclaration()) {
// initial exec model
unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
ARMConstantPoolValue *CPV =
@ -1254,7 +1253,7 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) {
// If symbol visibility is hidden, the extra load is not needed if
// the symbol is definitely defined in the current translation unit.
bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
bool isDecl = GV->isDeclaration() || GV->hasAvailableExternallyLinkage();
if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage()))
return false;
return RelocM != Reloc::Static && (isDecl || GV->isWeakForLinker());

View File

@ -346,8 +346,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
bool isCallOp = Modifier && !strcmp(Modifier, "call");
GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getMangledName(GV);
bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage());
bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static) {
printSuffixedName(Name, "$stub");
@ -1185,6 +1184,7 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
if (Subtarget->isTargetDarwin()) {
SwitchToDataSection("");
O << '\n';
// Output stubs for dynamically-linked functions
for (StringSet<>::iterator I = FnStubs.begin(), E = FnStubs.end();
I != E; ++I) {
@ -1227,7 +1227,7 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
O << "\t.indirect_symbol " << p << "\n";
O << "\t.long\tdyld_stub_binding_helper\n";
}
O << "\n";
O << '\n';
// Output non-lazy-pointers for external and common global variables.
if (!GVNonLazyPtrs.empty()) {

View File

@ -0,0 +1,67 @@
; RUN: llvm-as < %s | llc -relocation-model=static | FileCheck %s -check-prefix=STATIC
; RUN: llvm-as < %s | llc -relocation-model=pic | FileCheck %s -check-prefix=PIC
; RUN: llvm-as < %s | llc -relocation-model=dynamic-no-pic | FileCheck %s -check-prefix=DYNAMIC
; PR4482
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "armv6-apple-darwin2"
define i32 @foo(i64 %x) nounwind {
entry:
; STATIC: _foo:
; STATIC: bl _exact_log2
; STATIC: ldmfd sp!, {r7, pc}
; STATIC: .subsections_via_symbols
; PIC: _foo:
; PIC: bl L_exact_log2$stub
; PIC: ldmfd sp!, {r7, pc}
; DYNAMIC: _foo:
; DYNAMIC: bl L_exact_log2$stub
; DYNAMIC: ldmfd sp!, {r7, pc}
%A = call i32 @exact_log2(i64 %x)
ret i32 %A
}
define available_externally i32 @exact_log2(i64 %x) nounwind {
ret i32 4
}
; PIC: .section __TEXT,__picsymbolstub4,symbol_stubs,none,16
; PIC: L_exact_log2$stub:
; PIC: .indirect_symbol _exact_log2
; PIC: ldr ip, L_exact_log2$slp
; PIC: L_exact_log2$scv:
; PIC: add ip, pc, ip
; PIC: ldr pc, [ip, #0]
; PIC: L_exact_log2$slp:
; PIC: .long L_exact_log2$lazy_ptr-(L_exact_log2$scv+8)
; PIC: .lazy_symbol_pointer
; PIC: L_exact_log2$lazy_ptr:
; PIC: .indirect_symbol _exact_log2
; PIC: .long dyld_stub_binding_helper
; PIC: .subsections_via_symbols
; DYNAMIC: .section __TEXT,__symbol_stub4,symbol_stubs,none,12
; DYNAMIC: L_exact_log2$stub:
; DYNAMIC: .indirect_symbol _exact_log2
; DYNAMIC: ldr ip, L_exact_log2$slp
; DYNAMIC: ldr pc, [ip, #0]
; DYNAMIC: L_exact_log2$slp:
; DYNAMIC: .long L_exact_log2$lazy_ptr
; DYNAMIC: .lazy_symbol_pointer
; DYNAMIC: L_exact_log2$lazy_ptr:
; DYNAMIC: .indirect_symbol _exact_log2
; DYNAMIC: .long dyld_stub_binding_helper
; DYNAMIC: .subsections_via_symbols