mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Re-did 60519. It turns out Darwin's handling of hidden visibility symbols are a bit more complicate than I expected. Both declarations and weak definitions still need a stub indirection. However, the stubs are in data section and they contain the addresses of the actual symbols.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60571 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd730fa337
commit
ae94e59416
@ -830,9 +830,12 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
|
||||
/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol
|
||||
/// even in non-static mode.
|
||||
static bool GVIsIndirectSymbol(GlobalValue *GV, Reloc::Model RelocM) {
|
||||
return RelocM != Reloc::Static &&
|
||||
(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
|
||||
(GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode()));
|
||||
// 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();
|
||||
if (GV->hasHiddenVisibility() && (!isDecl && !GV->hasCommonLinkage()))
|
||||
return false;
|
||||
return RelocM != Reloc::Static && (isDecl || GV->mayBeOverridden());
|
||||
}
|
||||
|
||||
SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Mangler.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
@ -73,11 +74,15 @@ namespace {
|
||||
|
||||
/// GVNonLazyPtrs - Keeps the set of GlobalValues that require
|
||||
/// non-lazy-pointers for indirect access.
|
||||
std::set<std::string> GVNonLazyPtrs;
|
||||
StringSet<> GVNonLazyPtrs;
|
||||
|
||||
/// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
|
||||
/// visibility that require non-lazy-pointers for indirect access.
|
||||
StringSet<> HiddenGVNonLazyPtrs;
|
||||
|
||||
/// FnStubs - Keeps the set of external function GlobalAddresses that the
|
||||
/// asm printer should generate stubs for.
|
||||
std::set<std::string> FnStubs;
|
||||
StringSet<> FnStubs;
|
||||
|
||||
/// PCRelGVs - Keeps the set of GlobalValues used in pc relative
|
||||
/// constantpool.
|
||||
@ -141,7 +146,10 @@ namespace {
|
||||
if (!GV)
|
||||
Name += ACPV->getSymbol();
|
||||
if (ACPV->isNonLazyPointer()) {
|
||||
GVNonLazyPtrs.insert(Name);
|
||||
if (GV->hasHiddenVisibility())
|
||||
HiddenGVNonLazyPtrs.insert(Name);
|
||||
else
|
||||
GVNonLazyPtrs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
} else if (ACPV->isStub()) {
|
||||
FnStubs.insert(Name);
|
||||
@ -927,9 +935,8 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
|
||||
SwitchToDataSection("");
|
||||
|
||||
// Output stubs for dynamically-linked functions
|
||||
unsigned j = 1;
|
||||
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
i != e; ++i, ++j) {
|
||||
for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
i != e; ++i) {
|
||||
if (TM.getRelocationModel() == Reloc::PIC_)
|
||||
SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
|
||||
"none,16", 0);
|
||||
@ -940,10 +947,10 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
|
||||
EmitAlignment(2);
|
||||
O << "\t.code\t32\n";
|
||||
|
||||
std::string p = *i;
|
||||
const char *p = i->getKeyData();
|
||||
printSuffixedName(p, "$stub");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << "\n";
|
||||
O << "\t.indirect_symbol " << p << "\n";
|
||||
O << "\tldr ip, ";
|
||||
printSuffixedName(p, "$slp");
|
||||
O << "\n";
|
||||
@ -966,23 +973,37 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
|
||||
SwitchToDataSection(".lazy_symbol_pointer", 0);
|
||||
printSuffixedName(p, "$lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << "\n";
|
||||
O << "\t.indirect_symbol " << p << "\n";
|
||||
O << "\t.long\tdyld_stub_binding_helper\n";
|
||||
}
|
||||
O << "\n";
|
||||
|
||||
// Output non-lazy-pointers for external and common global variables.
|
||||
if (!GVNonLazyPtrs.empty())
|
||||
if (!GVNonLazyPtrs.empty()) {
|
||||
SwitchToDataSection(".non_lazy_symbol_pointer", 0);
|
||||
for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
|
||||
e = GVNonLazyPtrs.end(); i != e; ++i) {
|
||||
std::string p = *i;
|
||||
printSuffixedName(p, "$non_lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << "\n";
|
||||
O << "\t.long\t0\n";
|
||||
for (StringSet<>::iterator i = GVNonLazyPtrs.begin(),
|
||||
e = GVNonLazyPtrs.end(); i != e; ++i) {
|
||||
const char *p = i->getKeyData();
|
||||
printSuffixedName(p, "$non_lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << p << "\n";
|
||||
O << "\t.long\t0\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!HiddenGVNonLazyPtrs.empty()) {
|
||||
SwitchToSection(TAI->getDataSection());
|
||||
for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
|
||||
e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
|
||||
const char *p = i->getKeyData();
|
||||
EmitAlignment(2);
|
||||
printSuffixedName(p, "$non_lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.long " << p << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Emit initial debug information.
|
||||
// FIXME: Dwarf support.
|
||||
//DW.EndModule();
|
||||
|
@ -43,14 +43,14 @@
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include <set>
|
||||
#include "llvm/ADT/StringSet.h"
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(EmittedInsts, "Number of machine instrs printed");
|
||||
|
||||
namespace {
|
||||
struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter {
|
||||
std::set<std::string> FnStubs, GVStubs;
|
||||
StringSet<> FnStubs, GVStubs, HiddenGVStubs;
|
||||
const PPCSubtarget &Subtarget;
|
||||
|
||||
PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
|
||||
@ -387,10 +387,18 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
|
||||
|
||||
// External or weakly linked global variables need non-lazily-resolved stubs
|
||||
if (TM.getRelocationModel() != Reloc::Static) {
|
||||
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
|
||||
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
|
||||
GVStubs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
if (GV->isDeclaration() || GV->mayBeOverridden()) {
|
||||
if (GV->hasHiddenVisibility()) {
|
||||
if (!GV->isDeclaration() && !GV->hasCommonLinkage())
|
||||
O << Name;
|
||||
else {
|
||||
HiddenGVStubs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
}
|
||||
} else {
|
||||
GVStubs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
}
|
||||
if (GV->hasExternalWeakLinkage())
|
||||
ExtWeakSymbols.insert(GV);
|
||||
return;
|
||||
@ -416,7 +424,10 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
|
||||
void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) {
|
||||
std::string Name = getGlobalLinkName(GV);
|
||||
if (TM.getRelocationModel() != Reloc::Static) {
|
||||
GVStubs.insert(Name);
|
||||
if (GV->hasHiddenVisibility())
|
||||
HiddenGVStubs.insert(Name);
|
||||
else
|
||||
GVStubs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
return;
|
||||
}
|
||||
@ -979,51 +990,70 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
|
||||
|
||||
// Output stubs for dynamically-linked functions
|
||||
if (TM.getRelocationModel() == Reloc::PIC_) {
|
||||
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
i != e; ++i) {
|
||||
SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
|
||||
"pure_instructions,32");
|
||||
EmitAlignment(4);
|
||||
std::string p = *i;
|
||||
std::string L0p = (p[0]=='\"') ? "\"L0$" + p.substr(1) : "L0$" + p ;
|
||||
const char *p = i->getKeyData();
|
||||
bool hasQuote = p[0]=='\"';
|
||||
printSuffixedName(p, "$stub");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << '\n';
|
||||
O << "\t.indirect_symbol " << p << '\n';
|
||||
O << "\tmflr r0\n";
|
||||
O << "\tbcl 20,31," << L0p << '\n';
|
||||
O << L0p << ":\n";
|
||||
O << "\tbcl 20,31,";
|
||||
if (hasQuote)
|
||||
O << "\"L0$" << &p[1];
|
||||
else
|
||||
O << "L0$" << p;
|
||||
O << '\n';
|
||||
if (hasQuote)
|
||||
O << "\"L0$" << &p[1];
|
||||
else
|
||||
O << "L0$" << p;
|
||||
O << ":\n";
|
||||
O << "\tmflr r11\n";
|
||||
O << "\taddis r11,r11,ha16(";
|
||||
printSuffixedName(p, "$lazy_ptr");
|
||||
O << "-" << L0p << ")\n";
|
||||
O << "-";
|
||||
if (hasQuote)
|
||||
O << "\"L0$" << &p[1];
|
||||
else
|
||||
O << "L0$" << p;
|
||||
O << ")\n";
|
||||
O << "\tmtlr r0\n";
|
||||
if (isPPC64)
|
||||
O << "\tldu r12,lo16(";
|
||||
else
|
||||
O << "\tlwzu r12,lo16(";
|
||||
printSuffixedName(p, "$lazy_ptr");
|
||||
O << "-" << L0p << ")(r11)\n";
|
||||
O << "-";
|
||||
if (hasQuote)
|
||||
O << "\"L0$" << &p[1];
|
||||
else
|
||||
O << "L0$" << p;
|
||||
O << ")(r11)\n";
|
||||
O << "\tmtctr r12\n";
|
||||
O << "\tbctr\n";
|
||||
SwitchToDataSection(".lazy_symbol_pointer");
|
||||
printSuffixedName(p, "$lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << '\n';
|
||||
O << "\t.indirect_symbol " << p << '\n';
|
||||
if (isPPC64)
|
||||
O << "\t.quad dyld_stub_binding_helper\n";
|
||||
else
|
||||
O << "\t.long dyld_stub_binding_helper\n";
|
||||
}
|
||||
} else {
|
||||
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
i != e; ++i) {
|
||||
SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
|
||||
"pure_instructions,16");
|
||||
EmitAlignment(4);
|
||||
std::string p = *i;
|
||||
const char *p = i->getKeyData();
|
||||
printSuffixedName(p, "$stub");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << '\n';
|
||||
O << "\t.indirect_symbol " << p << '\n';
|
||||
O << "\tlis r11,ha16(";
|
||||
printSuffixedName(p, "$lazy_ptr");
|
||||
O << ")\n";
|
||||
@ -1038,7 +1068,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
|
||||
SwitchToDataSection(".lazy_symbol_pointer");
|
||||
printSuffixedName(p, "$lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *i << '\n';
|
||||
O << "\t.indirect_symbol " << p << '\n';
|
||||
if (isPPC64)
|
||||
O << "\t.quad dyld_stub_binding_helper\n";
|
||||
else
|
||||
@ -1061,12 +1091,12 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
|
||||
// Output stubs for external and common global variables.
|
||||
if (!GVStubs.empty()) {
|
||||
SwitchToDataSection(".non_lazy_symbol_pointer");
|
||||
for (std::set<std::string>::iterator I = GVStubs.begin(),
|
||||
E = GVStubs.end(); I != E; ++I) {
|
||||
std::string p = *I;
|
||||
for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end();
|
||||
i != e; ++i) {
|
||||
std::string p = i->getKeyData();
|
||||
printSuffixedName(p, "$non_lazy_ptr");
|
||||
O << ":\n";
|
||||
O << "\t.indirect_symbol " << *I << '\n';
|
||||
O << "\t.indirect_symbol " << p << '\n';
|
||||
if (isPPC64)
|
||||
O << "\t.quad\t0\n";
|
||||
else
|
||||
@ -1074,6 +1104,23 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!HiddenGVStubs.empty()) {
|
||||
SwitchToSection(TAI->getDataSection());
|
||||
for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
|
||||
i != e; ++i) {
|
||||
std::string p = i->getKeyData();
|
||||
EmitAlignment(isPPC64 ? 3 : 2);
|
||||
printSuffixedName(p, "$non_lazy_ptr");
|
||||
O << ":\n";
|
||||
if (isPPC64)
|
||||
O << "\t.quad\t";
|
||||
else
|
||||
O << "\t.long\t";
|
||||
O << p << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Emit initial debug information.
|
||||
DW.EndModule();
|
||||
|
||||
|
@ -141,8 +141,11 @@ bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV) const {
|
||||
// We never hae stubs if HasLazyResolverStubs=false or if in static mode.
|
||||
if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static)
|
||||
return false;
|
||||
|
||||
// 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();
|
||||
if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage())
|
||||
return false;
|
||||
return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
|
||||
GV->hasCommonLinkage() ||
|
||||
(GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode());
|
||||
GV->hasCommonLinkage() || isDecl;
|
||||
}
|
||||
|
@ -391,6 +391,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
FnStubs.insert(Name);
|
||||
printSuffixedName(Name, "$stub");
|
||||
}
|
||||
} else if (GV->hasHiddenVisibility()) {
|
||||
if (!GV->isDeclaration() && !GV->hasCommonLinkage())
|
||||
// Definition is not definitely in the current translation unit.
|
||||
O << Name;
|
||||
else {
|
||||
HiddenGVStubs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
}
|
||||
} else {
|
||||
GVStubs.insert(Name);
|
||||
printSuffixedName(Name, "$non_lazy_ptr");
|
||||
@ -875,6 +883,15 @@ void X86ATTAsmPrinter::printGVStub(const char *GV, const char *Prefix) {
|
||||
O << GV << "\n\t.long\t0\n";
|
||||
}
|
||||
|
||||
/// printHiddenGVStub - Print stub for a hidden global value.
|
||||
///
|
||||
void X86ATTAsmPrinter::printHiddenGVStub(const char *GV, const char *Prefix) {
|
||||
EmitAlignment(2);
|
||||
printSuffixedName(GV, "$non_lazy_ptr", Prefix);
|
||||
if (Prefix) O << Prefix;
|
||||
O << ":\n" << TAI->getData32bitsDirective() << GV << '\n';
|
||||
}
|
||||
|
||||
|
||||
bool X86ATTAsmPrinter::doFinalization(Module &M) {
|
||||
// Print out module-level global variables here.
|
||||
@ -908,9 +925,8 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
|
||||
SwitchToDataSection("");
|
||||
|
||||
// Output stubs for dynamically-linked functions
|
||||
unsigned j = 1;
|
||||
for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
i != e; ++i, ++j) {
|
||||
i != e; ++i) {
|
||||
SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
|
||||
"self_modifying_code+pure_instructions,5", 0);
|
||||
const char *p = i->getKeyData();
|
||||
@ -949,6 +965,13 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
|
||||
i != e; ++i)
|
||||
printGVStub(i->getKeyData());
|
||||
|
||||
if (!HiddenGVStubs.empty()) {
|
||||
SwitchToSection(TAI->getDataSection());
|
||||
for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end();
|
||||
i != e; ++i)
|
||||
printHiddenGVStub(i->getKeyData());
|
||||
}
|
||||
|
||||
// Emit final debug information.
|
||||
DW.EndModule();
|
||||
|
||||
|
@ -121,13 +121,14 @@ struct VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter {
|
||||
void printModuleLevelGV(const GlobalVariable* GVar);
|
||||
|
||||
void printGVStub(const char *GV, const char *Prefix = NULL);
|
||||
void printHiddenGVStub(const char *GV, const char *Prefix = NULL);
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
void emitFunctionHeader(const MachineFunction &MF);
|
||||
|
||||
// Necessary for Darwin to print out the apprioriate types of linker stubs
|
||||
StringSet<> FnStubs, GVStubs, LinkOnceStubs;
|
||||
StringSet<> FnStubs, GVStubs, HiddenGVStubs;
|
||||
|
||||
// Necessary for dllexport support
|
||||
StringSet<> DLLExportedFns, DLLExportedGVs;
|
||||
|
@ -40,10 +40,14 @@ bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV,
|
||||
if (TM.getRelocationModel() != Reloc::Static &&
|
||||
TM.getCodeModel() != CodeModel::Large) {
|
||||
if (isTargetDarwin()) {
|
||||
return (!isDirectCall &&
|
||||
(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
|
||||
GV->hasCommonLinkage() ||
|
||||
(GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())));
|
||||
bool isDecl = GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode();
|
||||
if (GV->hasHiddenVisibility() &&
|
||||
(Is64Bit || (!isDecl && !GV->hasCommonLinkage())))
|
||||
// If symbol visibility is hidden, the extra load is not needed if
|
||||
// target is x86-64 or the symbol is definitely defined in the current
|
||||
// translation unit.
|
||||
return false;
|
||||
return !isDirectCall && (isDecl || GV->mayBeOverridden());
|
||||
} else if (isTargetELF()) {
|
||||
// Extra load is needed for all externally visible.
|
||||
if (isDirectCall)
|
||||
|
12
test/CodeGen/PowerPC/hidden-vis-2.ll
Normal file
12
test/CodeGen/PowerPC/hidden-vis-2.ll
Normal file
@ -0,0 +1,12 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin9 | grep non_lazy_ptr | count 6
|
||||
|
||||
@x = external hidden global i32 ; <i32*> [#uses=1]
|
||||
@y = extern_weak hidden global i32 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
%1 = load i32* @y, align 4 ; <i32> [#uses=1]
|
||||
%2 = add i32 %1, %0 ; <i32> [#uses=1]
|
||||
ret i32 %2
|
||||
}
|
9
test/CodeGen/PowerPC/hidden-vis.ll
Normal file
9
test/CodeGen/PowerPC/hidden-vis.ll
Normal file
@ -0,0 +1,9 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin9 | not grep non_lazy_ptr
|
||||
|
||||
@x = weak hidden global i32 0 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
ret i32 %0
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 1
|
||||
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT
|
||||
; XFAIL: *
|
||||
|
||||
@x = weak hidden global i32 0 ; <i32*> [#uses=1]
|
||||
|
||||
|
15
test/CodeGen/X86/hidden-vis-3.ll
Normal file
15
test/CodeGen/X86/hidden-vis-3.ll
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep mov | count 3
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long | count 2
|
||||
; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin9 | not grep GOT
|
||||
|
||||
@x = external hidden global i32 ; <i32*> [#uses=1]
|
||||
@y = extern_weak hidden global i32 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
%1 = load i32* @y, align 4 ; <i32> [#uses=1]
|
||||
%2 = add i32 %1, %0 ; <i32> [#uses=1]
|
||||
ret i32 %2
|
||||
}
|
11
test/CodeGen/X86/hidden-vis-4.ll
Normal file
11
test/CodeGen/X86/hidden-vis-4.ll
Normal file
@ -0,0 +1,11 @@
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep non_lazy_ptr
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep long
|
||||
; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9 | grep comm
|
||||
|
||||
@x = common hidden global i32 0 ; <i32*> [#uses=1]
|
||||
|
||||
define i32 @t() nounwind readonly {
|
||||
entry:
|
||||
%0 = load i32* @x, align 4 ; <i32> [#uses=1]
|
||||
ret i32 %0
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user