mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 12:40:17 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75737 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0a2385455b
commit
4fb63d088b
@ -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());
|
||||
|
@ -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()) {
|
||||
|
67
test/CodeGen/ARM/stubs.ll
Normal file
67
test/CodeGen/ARM/stubs.ll
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user