<div dir="ltr"><div>Hi Chih-hung,<br><br>I don't know why it fails on OSX, but I am able to work-around the crash by specifying the triple in the RUN line:<br>-mtriple=x86_64-unknown-unknown<br><br></div><div>Conversely, you can probably reproduce the error on your platform by specifying a darwin triple:<br>-mtriple=x86_64-apple-darwin<br></div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 28, 2015 at 1:40 PM, Chih-hung Hsieh <span dir="ltr"><<a href="mailto:chh@google.com" target="_blank">chh@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I still don't know why this test failed on OSX and I cannot see any error on Linux.<div>Do you know why? If not, maybe I can remove that test case for now.</div><div>Thanks.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 28, 2015 at 12:11 PM, Sanjay Patel <span dir="ltr"><<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">'make check' is broken after this commit when building on OSX. Let me know if you need more info:<br><br>FAIL: LLVM :: CodeGen/PowerPC/emutls_generic.ll (4000 of 14310)<br>******************** TEST 'LLVM :: CodeGen/PowerPC/emutls_generic.ll' FAILED ********************<br>Script:<br>--<br>/myllvm/build/./bin/llc < /myllvm/llvm/test/CodeGen/PowerPC/emutls_generic.ll -emulated-tls -march=ppc64 -relocation-model=pic | /myllvm/build/./bin/FileCheck /myllvm/llvm/test/CodeGen/PowerPC/emutls_generic.ll<br>//myllvm/build/./bin/llc < /myllvm/llvm/test/CodeGen/PowerPC/emutls_generic.ll -emulated-tls -march=ppc32 -relocation-model=pic | /myllvm/build/./bin/FileCheck /myllvm/llvm/test/CodeGen/PowerPC/emutls_generic.ll<br>--<br>Exit Code: 2<br><br>Command Output (stderr):<br>--<br>Assertion failed: ((!IsEmuTLSVar || getObjFileLowering().getDataRelLocalSection()) && "Need relocatable local section for emulated TLS variables"), function EmitGlobalVariable, file /myllvm/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp, line 394.<br>0 llc 0x000000010fb1cb7e llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 46<br>1 llc 0x000000010fb1e449 PrintStackTraceSignalHandler(void*) + 25<br>2 llc 0x000000010fb1b139 llvm::sys::RunSignalHandlers() + 425<br>3 llc 0x000000010fb1e7ce SignalHandler(int) + 366<br>4 libsystem_platform.dylib 0x00007fff97782f1a _sigtramp + 26<br>5 libsystem_platform.dylib 0x0000000000000002 _sigtramp + 1753731330<br>6 llc 0x000000010fb1e46b raise + 27<br>7 llc 0x000000010fb1e522 abort + 18<br>8 llc 0x000000010fb1e501 __assert_rtn + 129<br>9 llc 0x000000010ecc0bdb llvm::AsmPrinter::EmitGlobalVariable(llvm::GlobalVariable const*) + 267<br>10 llc 0x000000010ecc6368 llvm::AsmPrinter::doFinalization(llvm::Module&) + 248<br>11 llc 0x000000010e5d6a24 (anonymous namespace)::PPCDarwinAsmPrinter::doFinalization(llvm::Module&) + 3588<br>12 llc 0x000000010f417b5c llvm::FPPassManager::doFinalization(llvm::Module&) + 92<br>13 llc 0x000000010f41865a (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) + 1946<br>14 llc 0x000000010f417cd6 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 310<br>15 llc 0x000000010f418bb1 llvm::legacy::PassManager::run(llvm::Module&) + 33<br>16 llc 0x000000010dbcfcf3 compileModule(char**, llvm::LLVMContext&) + 10755<br>17 llc 0x000000010dbcd286 main + 230<br>18 libdyld.dylib 0x00007fff92b6f5c9 start + 1<br>19 libdyld.dylib 0x0000000000000004 start + 1833503292<br>Stack dump:<br>0. Program arguments: /myllvm/build/./bin/llc -emulated-tls -march=ppc64 -relocation-model=pic <br>FileCheck error: '-' is empty.<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 28, 2015 at 10:24 AM, Chih-Hung Hsieh <span dir="ltr"><<a href="mailto:chh@google.com" target="_blank">chh@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chh<br>
Date: Tue Jul 28 11:24:05 2015<br>
New Revision: 243438<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D243438-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=P5KJdBUy1JGyRj4kinUdspFHSoRd6fSCZidx1sGx3Ig&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=243438&view=rev</a><br>
Log:<br>
Implement target independent TLS compatible with glibc's emutls.c.<br>
<br>
The 'common' section TLS is not implemented.<br>
Current C/C++ TLS variables are not placed in common section.<br>
DWARF debug info to get the address of TLS variables is not generated yet.<br>
<br>
clang and driver changes in <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D10524&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=RE4zkCP4nHHNz3qKKpyNDNds5TOc3whAaHtojQEuMbA&e=" rel="noreferrer" target="_blank">http://reviews.llvm.org/D10524</a><br>
<br>
Added -femulated-tls flag to select the emulated TLS model,<br>
which will be used for old targets like Android that do not<br>
support ELF TLS models.<br>
<br>
Added TargetLowering::LowerToTLSEmulatedModel as a target-independent<br>
function to convert a SDNode of TLS variable address to a function call<br>
to __emutls_get_address.<br>
<br>
Added into lib/Target/*/*ISelLowering.cpp to call LowerToTLSEmulatedModel<br>
for TLSModel::Emulated. Although all targets supporting ELF TLS models are<br>
enhanced, emulated TLS model has been tested only for Android ELF targets.<br>
Modified AsmPrinter.cpp to print the emutls_v.* and emutls_t.* variables for<br>
emulated TLS variables.<br>
Modified DwarfCompileUnit.cpp to skip some DIE for emulated TLS variabls.<br>
<br>
TODO: Add proper DIE for emulated TLS variables.<br>
Added new unit tests with emulated TLS.<br>
<br>
Differential Revision: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D10522&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=p6osBkc__w0rR72-h6OYGO9ipd8ZBUFmz64eB-0ueEM&e=" rel="noreferrer" target="_blank">http://reviews.llvm.org/D10522</a><br>
<br>
Added:<br>
llvm/trunk/test/CodeGen/AArch64/emutls.ll<br>
llvm/trunk/test/CodeGen/ARM/emutls1.ll<br>
llvm/trunk/test/CodeGen/Generic/emutls.ll<br>
llvm/trunk/test/CodeGen/X86/emutls-pic.ll<br>
llvm/trunk/test/CodeGen/X86/emutls-pie.ll<br>
llvm/trunk/test/CodeGen/X86/emutls.ll<br>
llvm/trunk/test/CodeGen/X86/fast-isel-emutls.ll<br>
llvm/trunk/test/CodeGen/X86/tls-android-negative.ll<br>
llvm/trunk/test/CodeGen/X86/tls-android.ll<br>
Modified:<br>
llvm/trunk/docs/LangRef.rst<br>
llvm/trunk/include/llvm/CodeGen/AsmPrinter.h<br>
llvm/trunk/include/llvm/CodeGen/CommandFlags.h<br>
llvm/trunk/include/llvm/MC/MCObjectFileInfo.h<br>
llvm/trunk/include/llvm/Target/TargetLowering.h<br>
llvm/trunk/include/llvm/Target/TargetOptions.h<br>
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp<br>
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp<br>
llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp<br>
llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp<br>
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp<br>
llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp<br>
llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp<br>
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
llvm/trunk/test/CodeGen/AArch64/arm64-tls-dynamic-together.ll<br>
llvm/trunk/test/CodeGen/ARM/tls-models.ll<br>
llvm/trunk/test/CodeGen/ARM/tls3.ll<br>
llvm/trunk/test/CodeGen/X86/tls-models.ll<br>
llvm/trunk/test/DebugInfo/ARM/tls.ll<br>
llvm/trunk/test/DebugInfo/X86/tls.ll<br>
llvm/trunk/test/Transforms/GlobalOpt/tls.ll<br>
<br>
Modified: llvm/trunk/docs/LangRef.rst<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_docs_LangRef.rst-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=SrJq1EVsOVPvfaGH7KTFfzTBhq-P6QTMZcnc6PfZbd0&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/LangRef.rst (original)<br>
+++ llvm/trunk/docs/LangRef.rst Tue Jul 28 11:24:05 2015<br>
@@ -494,6 +494,9 @@ model is not supported, or if a better c<br>
A model can also be specified in a alias, but then it only governs how<br>
the alias is accessed. It will not have any effect in the aliasee.<br>
<br>
+For platforms without linker support of ELF TLS model, the -femulated-tls<br>
+flag can be used to generate GCC compatible emulated TLS code.<br>
+<br>
.. _namedtypes:<br>
<br>
Structure Types<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_CodeGen_AsmPrinter.h-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=GLpvKEDGCyV3RU1-9bQofSuhO_JmrGJaDeonQF1NwXg&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Tue Jul 28 11:24:05 2015<br>
@@ -238,6 +238,11 @@ public:<br>
///<br>
void EmitJumpTableInfo();<br>
<br>
+ /// Emit the control variable for an emulated TLS variable.<br>
+ virtual void EmitEmulatedTLSControlVariable(const GlobalVariable *GV,<br>
+ MCSymbol *EmittedSym,<br>
+ bool AllZeroInitValue);<br>
+<br>
/// Emit the specified global variable to the .s file.<br>
virtual void EmitGlobalVariable(const GlobalVariable *GV);<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/CommandFlags.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_CodeGen_CommandFlags.h-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=r1XujeDVaAHYRtNLPBF3qmegMohLf2-bfFgqUdph3Zk&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/CommandFlags.h?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/CommandFlags.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/CommandFlags.h Tue Jul 28 11:24:05 2015<br>
@@ -219,6 +219,10 @@ FunctionSections("function-sections",<br>
cl::desc("Emit functions into separate sections"),<br>
cl::init(false));<br>
<br>
+cl::opt<bool> EmulatedTLS("emulated-tls",<br>
+ cl::desc("Use emulated TLS model"),<br>
+ cl::init(false));<br>
+<br>
cl::opt<bool> UniqueSectionNames("unique-section-names",<br>
cl::desc("Give unique names to every section"),<br>
cl::init(true));<br>
@@ -260,6 +264,7 @@ static inline TargetOptions InitTargetOp<br>
Options.DataSections = DataSections;<br>
Options.FunctionSections = FunctionSections;<br>
Options.UniqueSectionNames = UniqueSectionNames;<br>
+ Options.EmulatedTLS = EmulatedTLS;<br>
<br>
Options.MCOptions = InitMCTargetOptionsFromFlags();<br>
Options.JTType = JTableType;<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_MC_MCObjectFileInfo.h-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=0C-mhgfJT1H6HAVqYzW9N7GwgyA1ODBkZsqHH-M4TGM&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Tue Jul 28 11:24:05 2015<br>
@@ -216,6 +216,7 @@ public:<br>
MCSection *getTextSection() const { return TextSection; }<br>
MCSection *getDataSection() const { return DataSection; }<br>
MCSection *getBSSSection() const { return BSSSection; }<br>
+ MCSection *getReadOnlySection() const { return ReadOnlySection; }<br>
MCSection *getLSDASection() const { return LSDASection; }<br>
MCSection *getCompactUnwindSection() const { return CompactUnwindSection; }<br>
MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }<br>
<br>
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_Target_TargetLowering.h-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=ebYe6pmJoOTabqK_bowOhch91NjE4-ZJAWz2-1fV4-w&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)<br>
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Jul 28 11:24:05 2015<br>
@@ -2821,6 +2821,10 @@ public:<br>
virtual bool useLoadStackGuardNode() const {<br>
return false;<br>
}<br>
+<br>
+ /// Lower TLS global address SDNode for target independent emulated TLS model.<br>
+ virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,<br>
+ SelectionDAG &DAG) const;<br>
};<br>
<br>
/// Given an LLVM IR type and return type attributes, compute the return value<br>
<br>
Modified: llvm/trunk/include/llvm/Target/TargetOptions.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_include_llvm_Target_TargetOptions.h-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=tefM9y16iRUydB6i_w8d9rSTtEEwZAFhu87SPTSpOLU&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOptions.h?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Target/TargetOptions.h (original)<br>
+++ llvm/trunk/include/llvm/Target/TargetOptions.h Tue Jul 28 11:24:05 2015<br>
@@ -72,7 +72,7 @@ namespace llvm {<br>
UseInitArray(false), DisableIntegratedAS(false),<br>
CompressDebugSections(false), FunctionSections(false),<br>
DataSections(false), UniqueSectionNames(true), TrapUnreachable(false),<br>
- FloatABIType(FloatABI::Default),<br>
+ EmulatedTLS(false), FloatABIType(FloatABI::Default),<br>
AllowFPOpFusion(FPOpFusion::Standard), Reciprocals(TargetRecip()),<br>
JTType(JumpTable::Single),<br>
ThreadModel(ThreadModel::POSIX) {}<br>
@@ -172,6 +172,10 @@ namespace llvm {<br>
/// Emit target-specific trap instruction for 'unreachable' IR instructions.<br>
unsigned TrapUnreachable : 1;<br>
<br>
+ /// EmulatedTLS - This flag enables emulated TLS model, using emutls<br>
+ /// function in the runtime library..<br>
+ unsigned EmulatedTLS : 1;<br>
+<br>
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied<br>
/// on the command line. This setting may either be Default, Soft, or Hard.<br>
/// Default selects the target's default behavior. Soft selects the ABI for<br>
@@ -231,6 +235,7 @@ inline bool operator==(const TargetOptio<br>
ARE_EQUAL(PositionIndependentExecutable) &&<br>
ARE_EQUAL(UseInitArray) &&<br>
ARE_EQUAL(TrapUnreachable) &&<br>
+ ARE_EQUAL(EmulatedTLS) &&<br>
ARE_EQUAL(FloatABIType) &&<br>
ARE_EQUAL(AllowFPOpFusion) &&<br>
ARE_EQUAL(Reciprocals) &&<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_AsmPrinter.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=nDO8mNDtM9bwNzaz0cJvV-qRZUFcTXSuqkA9c9FFITw&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Tue Jul 28 11:24:05 2015<br>
@@ -343,8 +343,58 @@ MCSymbol *AsmPrinter::getSymbol(const Gl<br>
return TM.getSymbol(GV, *Mang);<br>
}<br>
<br>
+static MCSymbol *getOrCreateEmuTLSControlSym(MCSymbol *GVSym, MCContext &C) {<br>
+ return C.getOrCreateSymbol(Twine("__emutls_v.") + GVSym->getName());<br>
+}<br>
+<br>
+static MCSymbol *getOrCreateEmuTLSInitSym(MCSymbol *GVSym, MCContext &C) {<br>
+ return C.getOrCreateSymbol(Twine("__emutls_t.") + GVSym->getName());<br>
+}<br>
+<br>
+/// EmitEmulatedTLSControlVariable - Emit the control variable for an emulated TLS variable.<br>
+void AsmPrinter::EmitEmulatedTLSControlVariable(const GlobalVariable *GV,<br>
+ MCSymbol *EmittedSym,<br>
+ bool AllZeroInitValue) {<br>
+ // If there is init value, use .data.rel.local section;<br>
+ // otherwise use the .data section.<br>
+ MCSection *TLSVarSection = const_cast<MCSection*>(<br>
+ (GV->hasInitializer() && !AllZeroInitValue)<br>
+ ? getObjFileLowering().getDataRelLocalSection()<br>
+ : getObjFileLowering().getDataSection());<br>
+ OutStreamer->SwitchSection(TLSVarSection);<br>
+ MCSymbol *GVSym = getSymbol(GV);<br>
+ EmitLinkage(GV, EmittedSym); // same linkage as GV<br>
+ const DataLayout &DL = GV->getParent()->getDataLayout();<br>
+ uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());<br>
+ unsigned AlignLog = getGVAlignmentLog2(GV, DL);<br>
+ unsigned WordSize = DL.getPointerSize();<br>
+ unsigned Alignment = DL.getPointerABIAlignment();<br>
+ EmitAlignment(Log2_32(Alignment));<br>
+ OutStreamer->EmitLabel(EmittedSym);<br>
+ OutStreamer->EmitIntValue(Size, WordSize);<br>
+ OutStreamer->EmitIntValue((1 << AlignLog), WordSize);<br>
+ OutStreamer->EmitIntValue(0, WordSize);<br>
+ if (GV->hasInitializer() && !AllZeroInitValue) {<br>
+ OutStreamer->EmitSymbolValue(<br>
+ getOrCreateEmuTLSInitSym(GVSym, OutContext), WordSize);<br>
+ } else<br>
+ OutStreamer->EmitIntValue(0, WordSize);<br>
+ if (MAI->hasDotTypeDotSizeDirective())<br>
+ OutStreamer->emitELFSize(cast<MCSymbolELF>(EmittedSym),<br>
+ MCConstantExpr::create(4 * WordSize, OutContext));<br>
+ OutStreamer->AddBlankLine(); // End of the __emutls_v.* variable.<br>
+}<br>
+<br>
/// EmitGlobalVariable - Emit the specified global variable to the .s file.<br>
void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {<br>
+ bool IsEmuTLSVar =<br>
+ GV->getThreadLocalMode() != llvm::GlobalVariable::NotThreadLocal &&<br>
+ TM.Options.EmulatedTLS;<br>
+ assert((!IsEmuTLSVar || getObjFileLowering().getDataRelLocalSection()) &&<br>
+ "Need relocatable local section for emulated TLS variables");<br>
+ assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) &&<br>
+ "No emulated TLS variables in the common section");<br>
+<br>
if (GV->hasInitializer()) {<br>
// Check to see if this is a special global used by LLVM, if so, emit it.<br>
if (EmitSpecialLLVMGlobal(GV))<br>
@@ -355,7 +405,9 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
if (GlobalGOTEquivs.count(getSymbol(GV)))<br>
return;<br>
<br>
- if (isVerbose()) {<br>
+ if (isVerbose() && !IsEmuTLSVar) {<br>
+ // When printing the control variable __emutls_v.*,<br>
+ // we don't need to print the original TLS variable name.<br>
GV->printAsOperand(OutStreamer->GetCommentOS(),<br>
/*PrintType=*/false, GV->getParent());<br>
OutStreamer->GetCommentOS() << '\n';<br>
@@ -363,7 +415,12 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
}<br>
<br>
MCSymbol *GVSym = getSymbol(GV);<br>
- EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration());<br>
+ MCSymbol *EmittedSym = IsEmuTLSVar ?<br>
+ getOrCreateEmuTLSControlSym(GVSym, OutContext) : GVSym;<br>
+ // getOrCreateEmuTLSControlSym only creates the symbol with name and default attributes.<br>
+ // GV's or GVSym's attributes will be used for the EmittedSym.<br>
+<br>
+ EmitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration());<br>
<br>
if (!GV->hasInitializer()) // External globals require no extra code.<br>
return;<br>
@@ -374,7 +431,7 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
"' is already defined");<br>
<br>
if (MAI->hasDotTypeDotSizeDirective())<br>
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);<br>
+ OutStreamer->EmitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);<br>
<br>
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);<br>
<br>
@@ -386,6 +443,18 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
// sections and expected to be contiguous (e.g. ObjC metadata).<br>
unsigned AlignLog = getGVAlignmentLog2(GV, DL);<br>
<br>
+ bool AllZeroInitValue = false;<br>
+ const Constant *InitValue = GV->getInitializer();<br>
+ if (isa<ConstantAggregateZero>(InitValue))<br>
+ AllZeroInitValue = true;<br>
+ else {<br>
+ const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);<br>
+ if (InitIntValue && InitIntValue->isZero())<br>
+ AllZeroInitValue = true;<br>
+ }<br>
+ if (IsEmuTLSVar)<br>
+ EmitEmulatedTLSControlVariable(GV, EmittedSym, AllZeroInitValue);<br>
+<br>
for (const HandlerInfo &HI : Handlers) {<br>
NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled);<br>
HI.Handler->setSymbolSize(GVSym, Size);<br>
@@ -393,6 +462,8 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
<br>
// Handle common and BSS local symbols (.lcomm).<br>
if (GVKind.isCommon() || GVKind.isBSSLocal()) {<br>
+ assert(!(IsEmuTLSVar && GVKind.isCommon()) &&<br>
+ "No emulated TLS variables in the common section");<br>
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.<br>
unsigned Align = 1 << AlignLog;<br>
<br>
@@ -437,12 +508,21 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
return;<br>
}<br>
<br>
- MCSection *TheSection =<br>
+ if (IsEmuTLSVar && AllZeroInitValue)<br>
+ return; // No need of initialization values.<br>
+<br>
+ MCSymbol *EmittedInitSym = IsEmuTLSVar ?<br>
+ getOrCreateEmuTLSInitSym(GVSym, OutContext) : GVSym;<br>
+ // getOrCreateEmuTLSInitSym only creates the symbol with name and default attributes.<br>
+ // GV's or GVSym's attributes will be used for the EmittedInitSym.<br>
+<br>
+ MCSection *TheSection = IsEmuTLSVar ?<br>
+ getObjFileLowering().getReadOnlySection() :<br>
getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);<br>
<br>
// Handle the zerofill directive on darwin, which is a special form of BSS<br>
// emission.<br>
- if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {<br>
+ if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective() && !IsEmuTLSVar) {<br>
if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined.<br>
<br>
// .globl _foo<br>
@@ -462,7 +542,7 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
// TLOF class. This will also make it more obvious that stuff like<br>
// MCStreamer::EmitTBSSSymbol is macho specific and only called from macho<br>
// specific code.<br>
- if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) {<br>
+ if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective() && !IsEmuTLSVar) {<br>
// Emit the .tbss symbol<br>
MCSymbol *MangSym =<br>
OutContext.getOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));<br>
@@ -506,16 +586,18 @@ void AsmPrinter::EmitGlobalVariable(cons<br>
<br>
OutStreamer->SwitchSection(TheSection);<br>
<br>
- EmitLinkage(GV, GVSym);<br>
+ // emutls_t.* symbols are only used in the current compilation unit.<br>
+ if (!IsEmuTLSVar)<br>
+ EmitLinkage(GV, EmittedInitSym);<br>
EmitAlignment(AlignLog, GV);<br>
<br>
- OutStreamer->EmitLabel(GVSym);<br>
+ OutStreamer->EmitLabel(EmittedInitSym);<br>
<br>
EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());<br>
<br>
if (MAI->hasDotTypeDotSizeDirective())<br>
// .size foo, 42<br>
- OutStreamer->emitELFSize(cast<MCSymbolELF>(GVSym),<br>
+ OutStreamer->emitELFSize(cast<MCSymbolELF>(EmittedInitSym),<br>
MCConstantExpr::create(Size, OutContext));<br>
<br>
OutStreamer->AddBlankLine();<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_AsmPrinter_DwarfCompileUnit.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=o_FPQV9xd66zcyHAPttFYTXpa4A7b3hzyuHUFwPrX-w&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Jul 28 11:24:05 2015<br>
@@ -151,28 +151,32 @@ DIE *DwarfCompileUnit::getOrCreateGlobal<br>
DIELoc *Loc = new (DIEValueAllocator) DIELoc;<br>
const MCSymbol *Sym = Asm->getSymbol(Global);<br>
if (Global->isThreadLocal()) {<br>
- // FIXME: Make this work with -gsplit-dwarf.<br>
- unsigned PointerSize = Asm->getDataLayout().getPointerSize();<br>
- assert((PointerSize == 4 || PointerSize == 8) &&<br>
- "Add support for other sizes if necessary");<br>
- // Based on GCC's support for TLS:<br>
- if (!DD->useSplitDwarf()) {<br>
- // 1) Start with a constNu of the appropriate pointer size<br>
- addUInt(*Loc, dwarf::DW_FORM_data1,<br>
- PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u);<br>
- // 2) containing the (relocated) offset of the TLS variable<br>
- // within the module's TLS block.<br>
- addExpr(*Loc, dwarf::DW_FORM_udata,<br>
- Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));<br>
+ if (Asm->TM.Options.EmulatedTLS) {<br>
+ // TODO: add debug info for emulated thread local mode.<br>
} else {<br>
- addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);<br>
- addUInt(*Loc, dwarf::DW_FORM_udata,<br>
- DD->getAddressPool().getIndex(Sym, /* TLS */ true));<br>
+ // FIXME: Make this work with -gsplit-dwarf.<br>
+ unsigned PointerSize = Asm->getDataLayout().getPointerSize();<br>
+ assert((PointerSize == 4 || PointerSize == 8) &&<br>
+ "Add support for other sizes if necessary");<br>
+ // Based on GCC's support for TLS:<br>
+ if (!DD->useSplitDwarf()) {<br>
+ // 1) Start with a constNu of the appropriate pointer size<br>
+ addUInt(*Loc, dwarf::DW_FORM_data1,<br>
+ PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u);<br>
+ // 2) containing the (relocated) offset of the TLS variable<br>
+ // within the module's TLS block.<br>
+ addExpr(*Loc, dwarf::DW_FORM_udata,<br>
+ Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));<br>
+ } else {<br>
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);<br>
+ addUInt(*Loc, dwarf::DW_FORM_udata,<br>
+ DD->getAddressPool().getIndex(Sym, /* TLS */ true));<br>
+ }<br>
+ // 3) followed by an OP to make the debugger do a TLS lookup.<br>
+ addUInt(*Loc, dwarf::DW_FORM_data1,<br>
+ DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address<br>
+ : dwarf::DW_OP_form_tls_address);<br>
}<br>
- // 3) followed by an OP to make the debugger do a TLS lookup.<br>
- addUInt(*Loc, dwarf::DW_FORM_data1,<br>
- DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address<br>
- : dwarf::DW_OP_form_tls_address);<br>
} else {<br>
DD->addArangeLabel(SymbolCU(this, Sym));<br>
addOpAddress(*Loc, Sym);<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_CodeGen_SelectionDAG_TargetLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=o8es1I6Ni5_ZHdQe8d21I0pfFms8hU8IDq7i6HwTeF0&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -3044,3 +3044,46 @@ bool TargetLowering::expandFP_TO_SINT(SD<br>
DAG.getConstant(0, dl, NVT), Ret, ISD::SETLT);<br>
return true;<br>
}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Implementation of Emulated TLS Model<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+SDValue TargetLowering::LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,<br>
+ SelectionDAG &DAG) const {<br>
+ // Access to address of TLS varialbe xyz is lowered to a function call:<br>
+ // __emutls_get_address( address of global variable named "__emutls_v.xyz" )<br>
+ EVT PtrVT = getPointerTy(DAG.getDataLayout());<br>
+ PointerType *VoidPtrType = Type::getInt8PtrTy(*DAG.getContext());<br>
+ SDLoc dl(GA);<br>
+<br>
+ ArgListTy Args;<br>
+ ArgListEntry Entry;<br>
+ std::string NameString = ("__emutls_v." + GA->getGlobal()->getName()).str();<br>
+ Module *VariableModule = const_cast<Module*>(GA->getGlobal()->getParent());<br>
+ StringRef EmuTlsVarName(NameString);<br>
+ GlobalVariable *EmuTlsVar = VariableModule->getNamedGlobal(EmuTlsVarName);<br>
+ if (!EmuTlsVar)<br>
+ EmuTlsVar = dyn_cast_or_null<GlobalVariable>(<br>
+ VariableModule->getOrInsertGlobal(EmuTlsVarName, VoidPtrType));<br>
+ Entry.Node = DAG.getGlobalAddress(EmuTlsVar, dl, PtrVT);<br>
+ Entry.Ty = VoidPtrType;<br>
+ Args.push_back(Entry);<br>
+<br>
+ SDValue EmuTlsGetAddr = DAG.getExternalSymbol("__emutls_get_address", PtrVT);<br>
+<br>
+ TargetLowering::CallLoweringInfo CLI(DAG);<br>
+ CLI.setDebugLoc(dl).setChain(DAG.getEntryNode());<br>
+ CLI.setCallee(CallingConv::C, VoidPtrType, EmuTlsGetAddr, std::move(Args), 0);<br>
+ std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);<br>
+<br>
+ // TLSADDR will be codegen'ed as call. Inform MFI that function has calls.<br>
+ // At last for X86 targets, maybe good for other targets too?<br>
+ MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();<br>
+ MFI->setAdjustsStack(true); // Is this only for X86 target?<br>
+ MFI->setHasCalls(true);<br>
+<br>
+ assert((GA->getOffset() == 0) &&<br>
+ "Emulated TLS must have zero offset in GlobalAddressSDNode");<br>
+ return CallResult.first;<br>
+}<br>
<br>
Modified: llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_AArch64_AArch64ISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=F4l77v9F612omrUiboqwKYicAekQsolQvHGhzzY25eE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/AArch64/AArch64ISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -3404,6 +3404,10 @@ AArch64TargetLowering::LowerELFGlobalTLS<br>
const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);<br>
<br>
TLSModel::Model Model = getTargetMachine().getTLSModel(GA->getGlobal());<br>
+<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(GA, DAG);<br>
+<br>
if (!EnableAArch64ELFLocalDynamicTLSGeneration) {<br>
if (Model == TLSModel::LocalDynamic)<br>
Model = TLSModel::GeneralDynamic;<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_ARM_ARMISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=8cmOvt64ZNgusw2c3u4W9vYmU732lGrsNGY174DjEP4&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -2583,6 +2583,8 @@ ARMTargetLowering::LowerGlobalTLSAddress<br>
assert(Subtarget->isTargetELF() &&<br>
"TLS not implemented for non-ELF targets");<br>
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(GA, DAG);<br>
<br>
TLSModel::Model model = getTargetMachine().getTLSModel(GA->getGlobal());<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_Mips_MipsISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=QIEelUAvXatUbupsrokL01r3RU9HOmZXmhbRxHD5Tk8&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -1723,6 +1723,9 @@ lowerGlobalTLSAddress(SDValue Op, Select<br>
// Local Exec TLS Model.<br>
<br>
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(GA, DAG);<br>
+<br>
SDLoc DL(GA);<br>
const GlobalValue *GV = GA->getGlobal();<br>
EVT PtrVT = getPointerTy(DAG.getDataLayout());<br>
<br>
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_PowerPC_PPCISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=TTs6OWM91451bCDtKaUXuihqfw1kaXplM_pis26DynA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -2085,6 +2085,9 @@ SDValue PPCTargetLowering::LowerGlobalTL<br>
// large models could be added if users need it, at the cost of<br>
// additional complexity.<br>
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(GA, DAG);<br>
+<br>
SDLoc dl(GA);<br>
const GlobalValue *GV = GA->getGlobal();<br>
EVT PtrVT = getPointerTy(DAG.getDataLayout());<br>
<br>
Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_Sparc_SparcISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=BfZtalGQGT1f_KwBoY7ypmDqgllS9lv0Y4ymr_578YU&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -1872,6 +1872,9 @@ SDValue SparcTargetLowering::LowerGlobal<br>
SelectionDAG &DAG) const {<br>
<br>
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(GA, DAG);<br>
+<br>
SDLoc DL(GA);<br>
const GlobalValue *GV = GA->getGlobal();<br>
EVT PtrVT = getPointerTy(DAG.getDataLayout());<br>
<br>
Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_SystemZ_SystemZISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=dbUkhOjhHtGXarJhyDm2ZAsJCmCyb3SMWnJCiDRbfls&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -2485,6 +2485,8 @@ SDValue SystemZTargetLowering::lowerTLSG<br>
<br>
SDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node,<br>
SelectionDAG &DAG) const {<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(Node, DAG);<br>
SDLoc DL(Node);<br>
const GlobalValue *GV = Node->getGlobal();<br>
EVT PtrVT = getPointerTy(DAG.getDataLayout());<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Target_X86_X86ISelLowering.cpp-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=X-RwgCL56NzPraEFhR90QzK89_gnF5r6dNPQLEJRqC0&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Jul 28 11:24:05 2015<br>
@@ -11645,6 +11645,8 @@ X86TargetLowering::LowerGlobalTLSAddress<br>
auto PtrVT = getPointerTy(DAG.getDataLayout());<br>
<br>
if (Subtarget->isTargetELF()) {<br>
+ if (DAG.getTarget().Options.EmulatedTLS)<br>
+ return LowerToTLSEmulatedModel(GA, DAG);<br>
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);<br>
switch (model) {<br>
case TLSModel::GeneralDynamic:<br>
<br>
Modified: llvm/trunk/test/CodeGen/AArch64/arm64-tls-dynamic-together.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_AArch64_arm64-2Dtls-2Ddynamic-2Dtogether.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=HpWzrja0zSrym1PsY83hfcxIsqUY4f8RT8dxcSDjO90&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/arm64-tls-dynamic-together.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/arm64-tls-dynamic-together.ll (original)<br>
+++ llvm/trunk/test/CodeGen/AArch64/arm64-tls-dynamic-together.ll Tue Jul 28 11:24:05 2015<br>
@@ -1,4 +1,7 @@<br>
-; RUN: llc -O0 -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s<br>
+; RUN: llc -O0 -mtriple=arm64-none-linux-gnu -relocation-model=pic \<br>
+; RUN: -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=NOEMU %s<br>
+; RUN: llc -emulated-tls -O0 -mtriple=arm64-none-linux-gnu -relocation-model=pic \<br>
+; RUN: -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=EMU %s<br>
<br>
; If the .tlsdesccall and blr parts are emitted completely separately (even with<br>
; glue) then LLVM will separate them quite happily (with a spill at O0, hence<br>
@@ -13,6 +16,40 @@ define i32 @test_generaldynamic() {<br>
%val = load i32, i32* @general_dynamic_var<br>
ret i32 %val<br>
<br>
-; CHECK: .tlsdesccall general_dynamic_var<br>
-; CHECK-NEXT: blr {{x[0-9]+}}<br>
+; NOEMU: .tlsdesccall general_dynamic_var<br>
+; NOEMU-NEXT: blr {{x[0-9]+}}<br>
+; NOEMU-NOT: __emutls_v.general_dynamic_var:<br>
+<br>
+; EMU: adrp{{.+}}__emutls_v.general_dynamic_var<br>
+; EMU: bl __emutls_get_address<br>
+<br>
+; EMU-NOT: __emutls_v.general_dynamic_var<br>
+; EMU-NOT: __emutls_t.general_dynamic_var<br>
+}<br>
+<br>
+@emulated_init_var = thread_local global i32 37, align 8<br>
+<br>
+define i32 @test_emulated_init() {<br>
+; COMMON-LABEL: test_emulated_init:<br>
+<br>
+ %val = load i32, i32* @emulated_init_var<br>
+ ret i32 %val<br>
+<br>
+; EMU: adrp{{.+}}__emutls_v.emulated_init_var<br>
+; EMU: bl __emutls_get_address<br>
+<br>
+; EMU-NOT: __emutls_v.general_dynamic_var:<br>
+<br>
+; EMU: .align 3<br>
+; EMU-LABEL: __emutls_v.emulated_init_var:<br>
+; EMU-NEXT: .xword 4<br>
+; EMU-NEXT: .xword 8<br>
+; EMU-NEXT: .xword 0<br>
+; EMU-NEXT: .xword __emutls_t.emulated_init_var<br>
+<br>
+; EMU-LABEL: __emutls_t.emulated_init_var:<br>
+; EMU-NEXT: .word 37<br>
}<br>
+<br>
+; CHECK-NOT: __emutls_v.general_dynamic_var:<br>
+; EMU-NOT: __emutls_t.general_dynamic_var<br>
<br>
Added: llvm/trunk/test/CodeGen/AArch64/emutls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_AArch64_emutls.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=ymj8O3WlyIFEhi3cjflaXLdUMmUhVeNKF7VdFBtLSos&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/emutls.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/AArch64/emutls.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AArch64/emutls.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,368 @@<br>
+; RUN: llc -emulated-tls -mtriple=arm-linux-android \<br>
+; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s<br>
+; RUN: llc -emulated-tls -mtriple=aarch64-linux-android \<br>
+; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM64 %s<br>
+<br>
+; Copied from X86/emutls.ll<br>
+<br>
+; Use my_emutls_get_address like __emutls_get_address.<br>
+@my_emutls_v_xyz = external global i8*, align 4<br>
+declare i8* @my_emutls_get_address(i8*)<br>
+<br>
+define i32 @my_get_xyz() {<br>
+; ARM32-LABEL: my_get_xyz:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl my_emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldr r0, [r0]<br>
+; ARM64-LABEL: my_get_xyz:<br>
+; ARM64: adrp x0, :got:my_emutls_v_xyz<br>
+; ARM64-NEXT: ldr x0, [x0, :got_lo12:my_emutls_v_xyz]<br>
+; ARM64-NEXT: bl my_emutls_get_address<br>
+; ARM64-NEXT: ldr w0, [x0]<br>
+; ARM64-NEXT: ldp x29, x30, [sp]<br>
+<br>
+entry:<br>
+ %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))<br>
+ %0 = bitcast i8* %call to i32*<br>
+ %1 = load i32, i32* %0, align 4<br>
+ ret i32 %1<br>
+}<br>
+<br>
+@i1 = thread_local global i32 15<br>
+@i2 = external thread_local global i32<br>
+@i3 = internal thread_local global i32 15<br>
+@i4 = hidden thread_local global i32 15<br>
+@i5 = external hidden thread_local global i32<br>
+@s1 = thread_local global i16 15<br>
+@b1 = thread_local global i8 0<br>
+<br>
+define i32 @f1() {<br>
+; ARM32-LABEL: f1:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldr r0, [r0]<br>
+; ARM64-LABEL: f1:<br>
+; ARM64: adrp x0, :got:__emutls_v.i1<br>
+; ARM64-NEXT: ldr x0, [x0, :got_lo12:__emutls_v.i1]<br>
+; ARM64-NEXT: bl __emutls_get_address<br>
+; ARM64-NEXT: ldr w0, [x0]<br>
+; ARM64-NEXT: ldp x29, x30, [sp]<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i1<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f2() {<br>
+; ARM32-LABEL: f2:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: pop<br>
+; ARM64-LABEL: f2:<br>
+; ARM64: adrp x0, :got:__emutls_v.i1<br>
+; ARM64-NEXT: ldr x0, [x0, :got_lo12:__emutls_v.i1]<br>
+; ARM64-NEXT: bl __emutls_get_address<br>
+; ARM64-NEXT: ldp x29, x30, [sp]<br>
+<br>
+entry:<br>
+ ret i32* @i1<br>
+}<br>
+<br>
+define i32 @f3() nounwind {<br>
+; ARM32-LABEL: f3:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldr r0, [r0]<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i2<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f4() {<br>
+; ARM32-LABEL: f4:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: pop<br>
+<br>
+entry:<br>
+ ret i32* @i2<br>
+}<br>
+<br>
+define i32 @f5() nounwind {<br>
+; ARM32-LABEL: f5:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldr r0, [r0]<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i3<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f6() {<br>
+; ARM32-LABEL: f6:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: pop<br>
+<br>
+entry:<br>
+ ret i32* @i3<br>
+}<br>
+<br>
+define i32 @f7() {<br>
+; ARM32-LABEL: f7:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldr r0, [r0]<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i4<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f8() {<br>
+; ARM32-LABEL: f8:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: pop<br>
+<br>
+entry:<br>
+ ret i32* @i4<br>
+}<br>
+<br>
+define i32 @f9() {<br>
+; ARM32-LABEL: f9:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldr r0, [r0]<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i5<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f10() {<br>
+; ARM32-LABEL: f10:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: pop<br>
+<br>
+entry:<br>
+ ret i32* @i5<br>
+}<br>
+<br>
+define i16 @f11() {<br>
+; ARM32-LABEL: f11:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldrh r0, [r0]<br>
+<br>
+entry:<br>
+ %tmp1 = load i16, i16* @s1<br>
+ ret i16 %tmp1<br>
+}<br>
+<br>
+define i32 @f12() {<br>
+; ARM32-LABEL: f12:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldrsh r0, [r0]<br>
+<br>
+entry:<br>
+ %tmp1 = load i16, i16* @s1<br>
+ %tmp2 = sext i16 %tmp1 to i32<br>
+ ret i32 %tmp2<br>
+}<br>
+<br>
+define i8 @f13() {<br>
+; ARM32-LABEL: f13:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldrb r0, [r0]<br>
+; ARM32-NEXT: pop<br>
+<br>
+entry:<br>
+ %tmp1 = load i8, i8* @b1<br>
+ ret i8 %tmp1<br>
+}<br>
+<br>
+define i32 @f14() {<br>
+; ARM32-LABEL: f14:<br>
+; ARM32: ldr r0,<br>
+; ARM32-NEXT: ldr r1,<br>
+; ARM32: add r0, pc, r0<br>
+; ARM32-NEXT: ldr r0, [r1, r0]<br>
+; ARM32-NEXT: bl __emutls_get_address(PLT)<br>
+; ARM32-NEXT: ldrsb r0, [r0]<br>
+; ARM32-NEXT: pop<br>
+<br>
+entry:<br>
+ %tmp1 = load i8, i8* @b1<br>
+ %tmp2 = sext i8 %tmp1 to i32<br>
+ ret i32 %tmp2<br>
+}<br>
+<br>
+;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t.<br>
+<br>
+; ARM32 .section .data.rel.local,<br>
+; ARM32-LABEL: __emutls_v.i1:<br>
+; ARM32-NEXT: .long 4<br>
+; ARM32-NEXT: .long 4<br>
+; ARM32-NEXT: .long 0<br>
+; ARM32-NEXT: .long __emutls_t.i1<br>
+<br>
+; ARM32 .section .rodata,<br>
+; ARM32-LABEL: __emutls_t.i1:<br>
+; ARM32-NEXT: .long 15<br>
+<br>
+; ARM32-NOT: __emutls_v.i2<br>
+<br>
+; ARM32 .section .data.rel.local,<br>
+; ARM32-LABEL: __emutls_v.i3:<br>
+; ARM32-NEXT: .long 4<br>
+; ARM32-NEXT: .long 4<br>
+; ARM32-NEXT: .long 0<br>
+; ARM32-NEXT: .long __emutls_t.i3<br>
+<br>
+; ARM32 .section .rodata,<br>
+; ARM32-LABEL: __emutls_t.i3:<br>
+; ARM32-NEXT: .long 15<br>
+<br>
+; ARM32 .section .data.rel.local,<br>
+; ARM32-LABEL: __emutls_v.i4:<br>
+; ARM32-NEXT: .long 4<br>
+; ARM32-NEXT: .long 4<br>
+; ARM32-NEXT: .long 0<br>
+; ARM32-NEXT: .long __emutls_t.i4<br>
+<br>
+; ARM32 .section .rodata,<br>
+; ARM32-LABEL: __emutls_t.i4:<br>
+; ARM32-NEXT: .long 15<br>
+<br>
+; ARM32-NOT: __emutls_v.i5:<br>
+; ARM32 .hidden __emutls_v.i5<br>
+; ARM32-NOT: __emutls_v.i5:<br>
+<br>
+; ARM32 .section .data.rel.local,<br>
+; ARM32-LABEL: __emutls_v.s1:<br>
+; ARM32-NEXT: .long 2<br>
+; ARM32-NEXT: .long 2<br>
+; ARM32-NEXT: .long 0<br>
+; ARM32-NEXT: .long __emutls_t.s1<br>
+<br>
+; ARM32 .section .rodata,<br>
+; ARM32-LABEL: __emutls_t.s1:<br>
+; ARM32-NEXT: .short 15<br>
+<br>
+; ARM32 .section .data.rel.local,<br>
+; ARM32-LABEL: __emutls_v.b1:<br>
+; ARM32-NEXT: .long 1<br>
+; ARM32-NEXT: .long 1<br>
+; ARM32-NEXT: .long 0<br>
+; ARM32-NEXT: .long 0<br>
+<br>
+; ARM32-NOT: __emutls_t.b1<br>
+<br>
+;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t.<br>
+<br>
+; ARM64 .section .data.rel.local,<br>
+; ARM64-LABEL: __emutls_v.i1:<br>
+; ARM64-NEXT: .xword 4<br>
+; ARM64-NEXT: .xword 4<br>
+; ARM64-NEXT: .xword 0<br>
+; ARM64-NEXT: .xword __emutls_t.i1<br>
+<br>
+; ARM64 .section .rodata,<br>
+; ARM64-LABEL: __emutls_t.i1:<br>
+; ARM64-NEXT: .word 15<br>
+<br>
+; ARM64-NOT: __emutls_v.i2<br>
+<br>
+; ARM64 .section .data.rel.local,<br>
+; ARM64-LABEL: __emutls_v.i3:<br>
+; ARM64-NEXT: .xword 4<br>
+; ARM64-NEXT: .xword 4<br>
+; ARM64-NEXT: .xword 0<br>
+; ARM64-NEXT: .xword __emutls_t.i3<br>
+<br>
+; ARM64 .section .rodata,<br>
+; ARM64-LABEL: __emutls_t.i3:<br>
+; ARM64-NEXT: .word 15<br>
+<br>
+; ARM64 .section .data.rel.local,<br>
+; ARM64-LABEL: __emutls_v.i4:<br>
+; ARM64-NEXT: .xword 4<br>
+; ARM64-NEXT: .xword 4<br>
+; ARM64-NEXT: .xword 0<br>
+; ARM64-NEXT: .xword __emutls_t.i4<br>
+<br>
+; ARM64 .section .rodata,<br>
+; ARM64-LABEL: __emutls_t.i4:<br>
+; ARM64-NEXT: .word 15<br>
+<br>
+; ARM64-NOT: __emutls_v.i5:<br>
+; ARM64 .hidden __emutls_v.i5<br>
+; ARM64-NOT: __emutls_v.i5:<br>
+<br>
+; ARM64 .section .data.rel.local,<br>
+; ARM64-LABEL: __emutls_v.s1:<br>
+; ARM64-NEXT: .xword 2<br>
+; ARM64-NEXT: .xword 2<br>
+; ARM64-NEXT: .xword 0<br>
+; ARM64-NEXT: .xword __emutls_t.s1<br>
+<br>
+; ARM64 .section .rodata,<br>
+; ARM64-LABEL: __emutls_t.s1:<br>
+; ARM64-NEXT: .hword 15<br>
+<br>
+; ARM64 .section .data.rel.local,<br>
+; ARM64-LABEL: __emutls_v.b1:<br>
+; ARM64-NEXT: .xword 1<br>
+; ARM64-NEXT: .xword 1<br>
+; ARM64-NEXT: .xword 0<br>
+; ARM64-NEXT: .xword 0<br>
+<br>
+; ARM64-NOT: __emutls_t.b1<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM/emutls1.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_ARM_emutls1.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=UIoSWQhnzKokfQfSY8qpfP-yOaByDmgf6MzIbLlWB9U&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/emutls1.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/emutls1.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM/emutls1.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,31 @@<br>
+; RUN: llc < %s -emulated-tls -march=arm -mtriple=arm-linux-androideabi \<br>
+; RUN: | FileCheck %s<br>
+; RUN: llc < %s -emulated-tls -march=arm -mtriple=arm-linux-androideabi \<br>
+; RUN: -relocation-model=pic | FileCheck %s --check-prefix=PIC<br>
+<br>
+; Compared with tls1.ll, emulated mode should not use __aeabi_read_tp or __tls_get_addr.<br>
+<br>
+; CHECK-NOT: _aeabi_read_tp<br>
+; CHECK-NOT: _tls_get_addr<br>
+; CHECK: __emutls_get_addr<br>
+; CHECK-NOT: __aeabi_read_tp<br>
+; CHECK-NOT: _tls_get_addr<br>
+<br>
+; PIC-NOT: _aeabi_read_tp<br>
+; PIC-NOT: _tls_get_addr<br>
+; PIC: __emutls_get_addr<br>
+; PIC-NOT: _aeabi_read_tp<br>
+; PIC-NOT: _tls_get_addr<br>
+<br>
+@i = thread_local global i32 15 ; <i32*> [#uses=2]<br>
+<br>
+define i32 @f() {<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i ; <i32> [#uses=1]<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @g() {<br>
+entry:<br>
+ ret i32* @i<br>
+}<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/tls-models.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_ARM_tls-2Dmodels.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=UNkrLEHQDwAFxM29jeMKE2TrziHXVTAybL_klhRgV6g&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/tls-models.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/tls-models.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/tls-models.ll Tue Jul 28 11:24:05 2015<br>
@@ -1,5 +1,11 @@<br>
-; RUN: llc -march=arm -mtriple=arm-linux-gnueabi < %s | FileCheck -check-prefix=CHECK-NONPIC %s<br>
-; RUN: llc -march=arm -mtriple=arm-linux-gnueabi -relocation-model=pic < %s | FileCheck -check-prefix=CHECK-PIC %s<br>
+; RUN: llc -march=arm -mtriple=arm-linux-gnueabi < %s \<br>
+; RUN: | FileCheck -check-prefix=CHECK-NONPIC -check-prefix=COMMON %s<br>
+; RUN: llc -march=arm -mtriple=arm-linux-gnueabi -relocation-model=pic < %s \<br>
+; RUN: | FileCheck -check-prefix=CHECK-PIC -check-prefix=COMMON %s<br>
+; RUN: llc -emulated-tls -march=arm -mtriple=arm-linux-gnueabi < %s \<br>
+; RUN: | FileCheck -check-prefix=EMUNONPIC -check-prefix=EMU -check-prefix=COMMON %s<br>
+; RUN: llc -emulated-tls -march=arm -mtriple=arm-linux-gnueabi -relocation-model=pic < %s \<br>
+; RUN: | FileCheck -check-prefix=EMUPIC -check-prefix=EMU -check-prefix=COMMON %s<br>
<br>
<br>
@external_gd = external thread_local global i32<br>
@@ -20,23 +26,23 @@ define i32* @f1() {<br>
entry:<br>
ret i32* @external_gd<br>
<br>
+ ; COMMON-LABEL: f1:<br>
; Non-PIC code can use initial-exec, PIC code has to use general dynamic.<br>
- ; CHECK-NONPIC-LABEL: f1:<br>
; CHECK-NONPIC: external_gd(GOTTPOFF)<br>
- ; CHECK-PIC-LABEL: f1:<br>
; CHECK-PIC: external_gd(TLSGD)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
define i32* @f2() {<br>
entry:<br>
ret i32* @internal_gd<br>
<br>
+ ; COMMON-LABEL: f2:<br>
; Non-PIC code can use local exec, PIC code can use local dynamic,<br>
; but that is not implemented, so falls back to general dynamic.<br>
- ; CHECK-NONPIC-LABEL: f2:<br>
; CHECK-NONPIC: internal_gd(TPOFF)<br>
- ; CHECK-PIC-LABEL: f2:<br>
; CHECK-PIC: internal_gd(TLSGD)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
<br>
@@ -46,24 +52,24 @@ define i32* @f3() {<br>
entry:<br>
ret i32* @external_ld<br>
<br>
+ ; COMMON-LABEL: f3:<br>
; Non-PIC code can use initial exec, PIC should use local dynamic,<br>
; but that is not implemented, so falls back to general dynamic.<br>
- ; CHECK-NONPIC-LABEL: f3:<br>
; CHECK-NONPIC: external_ld(GOTTPOFF)<br>
- ; CHECK-PIC-LABEL: f3:<br>
; CHECK-PIC: external_ld(TLSGD)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
define i32* @f4() {<br>
entry:<br>
ret i32* @internal_ld<br>
<br>
+ ; COMMON-LABEL: f4:<br>
; Non-PIC code can use local exec, PIC code can use local dynamic,<br>
; but that is not implemented, so it falls back to general dynamic.<br>
- ; CHECK-NONPIC-LABEL: f4:<br>
; CHECK-NONPIC: internal_ld(TPOFF)<br>
- ; CHECK-PIC-LABEL: f4:<br>
; CHECK-PIC: internal_ld(TLSGD)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
<br>
@@ -73,22 +79,22 @@ define i32* @f5() {<br>
entry:<br>
ret i32* @external_ie<br>
<br>
+ ; COMMON-LABEL: f5:<br>
; Non-PIC and PIC code will use initial exec as specified.<br>
- ; CHECK-NONPIC-LABEL: f5:<br>
; CHECK-NONPIC: external_ie(GOTTPOFF)<br>
- ; CHECK-PIC-LABEL: f5:<br>
; CHECK-PIC: external_ie(GOTTPOFF)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
define i32* @f6() {<br>
entry:<br>
ret i32* @internal_ie<br>
<br>
+ ; COMMON-LABEL: f6:<br>
; Non-PIC code can use local exec, PIC code use initial exec as specified.<br>
- ; CHECK-NONPIC-LABEL: f6:<br>
; CHECK-NONPIC: internal_ie(TPOFF)<br>
- ; CHECK-PIC-LABEL: f6:<br>
; CHECK-PIC: internal_ie(GOTTPOFF)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
<br>
@@ -98,20 +104,52 @@ define i32* @f7() {<br>
entry:<br>
ret i32* @external_le<br>
<br>
+ ; COMMON-LABEL: f7:<br>
; Non-PIC and PIC code will use local exec as specified.<br>
- ; CHECK-NONPIC-LABEL: f7:<br>
; CHECK-NONPIC: external_le(TPOFF)<br>
- ; CHECK-PIC-LABEL: f7:<br>
; CHECK-PIC: external_le(TPOFF)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
<br>
define i32* @f8() {<br>
entry:<br>
ret i32* @internal_le<br>
<br>
+ ; COMMON-LABEL: f8:<br>
; Non-PIC and PIC code will use local exec as specified.<br>
- ; CHECK-NONPIC-LABEL: f8:<br>
; CHECK-NONPIC: internal_le(TPOFF)<br>
- ; CHECK-PIC-LABEL: f8:<br>
; CHECK-PIC: internal_le(TPOFF)<br>
+ ; EMU: __emutls_get_address<br>
}<br>
+<br>
+<br>
+; ----- emulated specified -----<br>
+<br>
+; External declaration has no initializer.<br>
+; Internal definition has initializer.<br>
+<br>
+; EMU-NOT: __emutls_t.external_gd<br>
+; EMU-NOT: __emutls_v.external_gd<br>
+; EMU: .align 2<br>
+; EMU-LABEL: __emutls_v.internal_gd:<br>
+; EMU-NEXT: .long 4<br>
+; EMU-NEXT: .long 4<br>
+; EMU-NEXT: .long 0<br>
+; EMU-NEXT: .long __emutls_t.internal_gd<br>
+; EMU-LABEL: __emutls_t.internal_gd:<br>
+; EMU-NEXT: .long 42<br>
+; EMU-NOT: __emutls_t.external_gd<br>
+<br>
+; __emutls_t and __emutls_v are the same for PIC and non-PIC modes.<br>
+<br>
+; EMU-NOT: __emutls_t.external_gd<br>
+; EMU-NOT: __emutls_v.external_gd<br>
+; EMU: .align 2<br>
+; EMU-LABEL: __emutls_v.internal_le:<br>
+; EMU-NEXT: .long 4<br>
+; EMU-NEXT: .long 4<br>
+; EMU-NEXT: .long 0<br>
+; EMU-NEXT: .long __emutls_t.internal_le<br>
+; EMU-LABEL: __emutls_t.internal_le:<br>
+; EMU-NEXT: .long 42<br>
+; EMU-NOT: __emutls_t.external_le<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/tls3.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_ARM_tls3.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=YeFq_9KWiYiVfq6V2OyWLBzMkISq9ZvXSvScy5LMvyY&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/tls3.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/tls3.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/tls3.ll Tue Jul 28 11:24:05 2015<br>
@@ -1,11 +1,34 @@<br>
; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \<br>
; RUN: grep "tbss"<br>
+; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \<br>
+; RUN: FileCheck %s -check-prefix=CHECK -check-prefix=NOEMU<br>
+; RUN: llc < %s -emulated-tls -march=arm -mtriple=arm-linux-gnueabi | \<br>
+; RUN: FileCheck %s -check-prefix=CHECK -check-prefix=EMU<br>
<br>
%struct.anon = type { i32, i32 }<br>
-@teste = internal thread_local global %struct.anon zeroinitializer ; <%struct.anon*> [#uses=1]<br>
+@teste = internal thread_local global %struct.anon zeroinitializer ; <%struct.anon*> [#uses=1]<br>
<br>
define i32 @main() {<br>
entry:<br>
- %tmp2 = load i32, i32* getelementptr (%struct.anon, %struct.anon* @teste, i32 0, i32 0), align 8 ; <i32> [#uses=1]<br>
- ret i32 %tmp2<br>
+ %tmp2 = load i32, i32* getelementptr (%struct.anon, %struct.anon* @teste, i32 0, i32 0), align 8 ; <i32> [#uses=1]<br>
+ ret i32 %tmp2<br>
}<br>
+<br>
+; CHECK-LABEL: main:<br>
+; NOEMU-NOT: __emutls_get_address<br>
+<br>
+; NOEMU: .section .tbss<br>
+; NOEMU-LABEL: teste:<br>
+; NOEMU-NEXT: .zero 8<br>
+<br>
+; CHECK-NOT: __emutls_t.teste<br>
+<br>
+; EMU: .align 2<br>
+; EMU-LABEL: __emutls_v.teste:<br>
+; EMU-NEXT: .long 8<br>
+; EMU-NEXT: .long 4<br>
+; EMU-NEXT: .long 0<br>
+; EMU-NEXT: .long 0<br>
+<br>
+; CHECK-NOT: teste:<br>
+; CHECK-NOT: __emutls_t.teste<br>
<br>
Added: llvm/trunk/test/CodeGen/Generic/emutls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_Generic_emutls.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=NSrHXfbPrENzjYI9BLQ5yDoqfG1XNSOs6rSztuYFF_I&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/emutls.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/Generic/emutls.ll (added)<br>
+++ llvm/trunk/test/CodeGen/Generic/emutls.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,298 @@<br>
+; RUN: llc < %s -emulated-tls -mtriple=arm-linux-android -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=ARM_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=arm-linux-androidabi -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=ARM_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-android -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=ARM_64 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=arm-linux-androidabi -relocation-model=pic -O3 \<br>
+; RUN: | FileCheck -check-prefix=ARM_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-android -relocation-model=pic -O3 \<br>
+; RUN: | FileCheck -check-prefix=ARM_64 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=arm-linux-androidabi -O3 \<br>
+; RUN: | FileCheck -check-prefix=ARM_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-android -O3 \<br>
+; RUN: | FileCheck -check-prefix=ARM_64 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=i686-linux-android -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=X86_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -march=x86 -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=X86_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=X86_64 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=mipsel-linux-android -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=MIPS_32 %s<br>
+; RUN: llc < %s -emulated-tls -mtriple=mips64el-linux-android -relocation-model=pic \<br>
+; RUN: | FileCheck -check-prefix=MIPS_64 %s<br>
+; RUN: llc < %s -emulated-tls -march=ppc64 -relocation-model=pic \<br>
+; RUN: | FileCheck %s<br>
+; RUN: llc < %s -emulated-tls -march=ppc32 -relocation-model=pic \<br>
+; RUN: | FileCheck %s<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic \<br>
+; RUN: | FileCheck %s<br>
+<br>
+; Make sure that TLS symbols are emitted in expected order.<br>
+<br>
+@external_x = external thread_local global i32, align 8<br>
+@external_y = thread_local global i8 7, align 2<br>
+@internal_y = internal thread_local global i64 9, align 16<br>
+<br>
+define i32* @get_external_x() {<br>
+entry:<br>
+ ret i32* @external_x<br>
+}<br>
+<br>
+define i8* @get_external_y() {<br>
+entry:<br>
+ ret i8* @external_y<br>
+}<br>
+<br>
+define i64* @get_internal_y() {<br>
+entry:<br>
+ ret i64* @internal_y<br>
+}<br>
+<br>
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; targets independent mode<br>
+; CHECK-LABEL: get_external_x:<br>
+; CHECK-NOT: _tls_get_address<br>
+; CHECK: __emutls_get_address<br>
+; CHECK-LABEL: get_external_y:<br>
+; CHECK: __emutls_get_address<br>
+; CHECK-NOT: _tls_get_address<br>
+; CHECK-LABEL: get_internal_y:<br>
+<br>
+; CHECK-NOT: __emutls_t.external_x:<br>
+; CHECK-NOT: __emutls_v.external_x:<br>
+<br>
+; CHECK-LABEL: __emutls_v.external_y:<br>
+; CHECK-LABEL: __emutls_t.external_y:<br>
+; CHECK: __emutls_t.external_y<br>
+<br>
+; CHECK-LABEL: __emutls_v.internal_y:<br>
+; CHECK-LABEL: __emutls_t.internal_y:<br>
+; CHECK: __emutls_t.internal_y<br>
+<br>
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32-bit mode<br>
+; ARM_32-LABEL: get_external_x:<br>
+; X86_32-LABEL: get_external_x:<br>
+; MIPS-LABEL: get_external_x:<br>
+<br>
+; ARM_32: bl __emutls_get_address<br>
+; ARM_32: .long __emutls_v.external_x<br>
+<br>
+; X86_32: movl __emutls_v.external_x<br>
+; X86_32: calll __emutls_get_address<br>
+<br>
+; ARM_32-LABEL: get_external_y:<br>
+; X86_32-LABEL: get_external_y:<br>
+; MIPS_32-LABEL: get_external_y:<br>
+<br>
+; ARM_32: bl __emutls_get_address<br>
+; ARM_32: .long __emutls_v.external_y<br>
+<br>
+; X86_32: movl __emutls_v.external_y<br>
+; X86_32: calll __emutls_get_address<br>
+<br>
+; ARM_32-LABEL: get_internal_y:<br>
+; X86_32-LABEL: get_internal_y:<br>
+; MIPS_32-LABEL: get_internal_y:<br>
+<br>
+; ARM_32: bl __emutls_get_address<br>
+; ARM_32: .long __emutls_v.internal_y<br>
+<br>
+; X86_32: movl __emutls_v.internal_y<br>
+; X86_32: calll __emutls_get_address<br>
+<br>
+; MIPS_32: lw {{.+}}(__emutls_v.internal_y<br>
+; MIPS_32: lw {{.+}}call16(__emutls_get_address<br>
+<br>
+; ARM_32-NOT: __emutls_t.external_x<br>
+; X86_32-NOT: __emutls_t.external_x<br>
+; MIPS_32-NOT: __emutls_t.external_x<br>
+<br>
+; ARM_32-NOT: __emutls_v.external_x:<br>
+; X86_32-NOT: __emutls_v.external_x:<br>
+; MIPS_32-NOT: __emutls_v.external_x:<br>
+<br>
+; ARM_32: .section .data.rel.local<br>
+; X86_32: .section .data.rel.local<br>
+; MIPS_32: .section .data.rel.local<br>
+<br>
+; ARM_32: .align 2<br>
+; X86_32: .align 4<br>
+; MIPS_32: .align 2<br>
+<br>
+; ARM_32-LABEL: __emutls_v.external_y:<br>
+; X86_32-LABEL: __emutls_v.external_y:<br>
+; MIPS_32-LABEL: __emutls_v.external_y:<br>
+<br>
+; ARM_32-NEXT: .long 1<br>
+; ARM_32-NEXT: .long 2<br>
+; ARM_32-NEXT: .long 0<br>
+; ARM_32-NEXT: .long __emutls_t.external_y<br>
+<br>
+; X86_32-NEXT: .long 1<br>
+; X86_32-NEXT: .long 2<br>
+; X86_32-NEXT: .long 0<br>
+; X86_32-NEXT: .long __emutls_t.external_y<br>
+<br>
+; ARM_32: .section .rodata,<br>
+; X86_32: .section .rodata,<br>
+; MIPS_32: .section .rodata,<br>
+<br>
+; ARM_32-LABEL: __emutls_t.external_y:<br>
+; X86_32-LABEL: __emutls_t.external_y:<br>
+; MIPS_32-LABEL: __emutls_t.external_y:<br>
+<br>
+; ARM_32-NEXT: .byte 7<br>
+; X86_32-NEXT: .byte 7<br>
+; MIPS_32-NEXT: .byte 7<br>
+<br>
+; ARM_32: .section .data.rel.local<br>
+; X86_32: .section .data.rel.local<br>
+; MIPS_32: .section .data.rel.local<br>
+<br>
+; ARM_32: .align 2<br>
+; X86_32: .align 4<br>
+; MIPS_32: .align 2<br>
+<br>
+; ARM_32-LABEL: __emutls_v.internal_y:<br>
+; X86_32-LABEL: __emutls_v.internal_y:<br>
+; MIPS_32-LABEL: __emutls_v.internal_y:<br>
+<br>
+; ARM_32-NEXT: .long 8<br>
+; ARM_32-NEXT: .long 16<br>
+; ARM_32-NEXT: .long 0<br>
+; ARM_32-NEXT: .long __emutls_t.internal_y<br>
+<br>
+; X86_32-NEXT: .long 8<br>
+; X86_32-NEXT: .long 16<br>
+; X86_32-NEXT: .long 0<br>
+; X86_32-NEXT: .long __emutls_t.internal_y<br>
+<br>
+; MIPS_32-NEXT: .4byte 8<br>
+; MIPS_32-NEXT: .4byte 16<br>
+; MIPS_32-NEXT: .4byte 0<br>
+; MIPS_32-NEXT: .4byte __emutls_t.internal_y<br>
+<br>
+; ARM_32-LABEL: __emutls_t.internal_y:<br>
+; X86_32-LABEL: __emutls_t.internal_y:<br>
+; MIPS_32-LABEL: __emutls_t.internal_y:<br>
+<br>
+; ARM_32-NEXT: .long 9<br>
+; ARM_32-NEXT: .long 0<br>
+; X86_32-NEXT: .quad 9<br>
+; MIPS_32-NEXT: .8byte 9<br>
+<br>
+<br>
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64-bit mode<br>
+; X86_64-LABEL: get_external_x:<br>
+; ARM_64-LABEL: get_external_x:<br>
+; MIPS_64-LABEL: get_external_x:<br>
+<br>
+; X86_64: __emutls_v.external_x<br>
+; X86_64: __emutls_get_address<br>
+<br>
+; ARM_64: __emutls_v.external_x<br>
+; ARM_64: __emutls_get_address<br>
+<br>
+; X86_64-LABEL: get_external_y:<br>
+; ARM_64-LABEL: get_external_y:<br>
+; MIPS_64-LABEL: get_external_y:<br>
+<br>
+; X86_64: __emutls_v.external_y<br>
+; X86_64: __emutls_get_address<br>
+<br>
+; ARM_64: __emutls_v.external_y<br>
+; ARM_64: __emutls_get_address<br>
+<br>
+; X86_64-LABEL: get_internal_y:<br>
+; ARM_64-LABEL: get_internal_y:<br>
+; MIPS_64-LABEL: get_internal_y:<br>
+<br>
+; X86_64: __emutls_v.internal_y<br>
+; X86_64: __emutls_get_address<br>
+<br>
+; ARM_64: __emutls_v.internal_y<br>
+; ARM_64: __emutls_get_address<br>
+<br>
+; MIPS_64: ld {{.+}}(__emutls_v.internal_y<br>
+; MIPS_64: ld {{.+}}call16(__emutls_get_address<br>
+<br>
+; ARM_64-NOT: __emutls_t.external_x<br>
+; X86_64-NOT: __emutls_t.external_x<br>
+; MIPS_64-NOT: __emutls_t.external_x<br>
+<br>
+; X86_64-NOT: __emutls_v.external_x:<br>
+; ARM_64-NOT: __emutls_v.external_x:<br>
+; MIPS_64-NOT: __emutls_v.external_x:<br>
+<br>
+; X86_64: .align 8<br>
+; ARM_64: .align 3<br>
+<br>
+; X86_64-LABEL: __emutls_v.external_y:<br>
+; ARM_64-LABEL: __emutls_v.external_y:<br>
+; MIPS_64-LABEL: __emutls_v.external_y:<br>
+<br>
+; X86_64-NEXT: .quad 1<br>
+; X86_64-NEXT: .quad 2<br>
+; X86_64-NEXT: .quad 0<br>
+; X86_64-NEXT: .quad __emutls_t.external_y<br>
+<br>
+; ARM_64-NEXT: .xword 1<br>
+; ARM_64-NEXT: .xword 2<br>
+; ARM_64-NEXT: .xword 0<br>
+; ARM_64-NEXT: .xword __emutls_t.external_y<br>
+<br>
+; X86_64-NOT: __emutls_v.external_x:<br>
+; ARM_64-NOT: __emutls_v.external_x:<br>
+; MIPS_64-NOT: __emutls_v.external_x:<br>
+<br>
+; ARM_64: .section .rodata,<br>
+; X86_64: .section .rodata,<br>
+; MIPS_64: .section .rodata,<br>
+<br>
+; X86_64-LABEL: __emutls_t.external_y:<br>
+; ARM_64-LABEL: __emutls_t.external_y:<br>
+; MIPS_64-LABEL: __emutls_t.external_y:<br>
+<br>
+; X86_64-NEXT: .byte 7<br>
+; ARM_64-NEXT: .byte 7<br>
+; MIPS_64-NEXT: .byte 7<br>
+<br>
+; ARM_64: .section .data.rel.local<br>
+; X86_64: .section .data.rel.local<br>
+; MIPS_64: .section .data.rel.local<br>
+<br>
+; X86_64: .align 8<br>
+; ARM_64: .align 3<br>
+; MIPS_64: .align 3<br>
+<br>
+; X86_64-LABEL: __emutls_v.internal_y:<br>
+; ARM_64-LABEL: __emutls_v.internal_y:<br>
+; MIPS_64-LABEL: __emutls_v.internal_y:<br>
+<br>
+; X86_64-NEXT: .quad 8<br>
+; X86_64-NEXT: .quad 16<br>
+; X86_64-NEXT: .quad 0<br>
+; X86_64-NEXT: .quad __emutls_t.internal_y<br>
+<br>
+; ARM_64-NEXT: .xword 8<br>
+; ARM_64-NEXT: .xword 16<br>
+; ARM_64-NEXT: .xword 0<br>
+; ARM_64-NEXT: .xword __emutls_t.internal_y<br>
+<br>
+; MIPS_64-NEXT: .8byte 8<br>
+; MIPS_64-NEXT: .8byte 16<br>
+; MIPS_64-NEXT: .8byte 0<br>
+; MIPS_64-NEXT: .8byte __emutls_t.internal_y<br>
+<br>
+; ARM_64: .section .rodata,<br>
+; X86_64: .section .rodata,<br>
+; MIPS_64: .section .rodata,<br>
+<br>
+; X86_64-LABEL: __emutls_t.internal_y:<br>
+; ARM_64-LABEL: __emutls_t.internal_y:<br>
+; MIPS_64-LABEL: __emutls_t.internal_y:<br>
+<br>
+; X86_64-NEXT: .quad 9<br>
+; ARM_64-NEXT: .xword 9<br>
+; MIPS_64-NEXT: .8byte 9<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/emutls-pic.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_emutls-2Dpic.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=8fO2f1G09-nAKXMG9iVwtjjCzfUJdJMiFFT_k077KFs&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/emutls-pic.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/emutls-pic.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/emutls-pic.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,168 @@<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X32 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X64 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X32 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s<br>
+<br>
+; Use my_emutls_get_address like __emutls_get_address.<br>
+@my_emutls_v_xyz = external global i8*, align 4<br>
+declare i8* @my_emutls_get_address(i8*)<br>
+<br>
+define i32 @my_get_xyz() {<br>
+; X32-LABEL: my_get_xyz:<br>
+; X32: movl my_emutls_v_xyz@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll my_emutls_get_address@PLT<br>
+; X64-LABEL: my_get_xyz:<br>
+; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq my_emutls_get_address@PLT<br>
+; X64-NEXT: movl (%rax), %eax<br>
+<br>
+entry:<br>
+ %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))<br>
+ %0 = bitcast i8* %call to i32*<br>
+ %1 = load i32, i32* %0, align 4<br>
+ ret i32 %1<br>
+}<br>
+<br>
+@i = thread_local global i32 15<br>
+@j = internal thread_local global i32 42<br>
+@k = internal thread_local global i32 0, align 8<br>
+<br>
+define i32 @f1() {<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+; X32-LABEL: f1:<br>
+; X32: movl __emutls_v.i@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X64-LABEL: f1:<br>
+; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+; X64-NEXT: movl (%rax), %eax<br>
+<br>
+@i2 = external thread_local global i32<br>
+<br>
+define i32* @f2() {<br>
+entry:<br>
+ ret i32* @i<br>
+}<br>
+<br>
+; X32-LABEL: f2:<br>
+; X64-LABEL: f2:<br>
+<br>
+<br>
+define i32 @f3() {<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i ; <i32> [#uses=1]<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+; X32-LABEL: f3:<br>
+; X64-LABEL: f3:<br>
+<br>
+<br>
+define i32* @f4() nounwind {<br>
+entry:<br>
+ ret i32* @i<br>
+}<br>
+<br>
+; X32-LABEL: f4:<br>
+; X64-LABEL: f4:<br>
+<br>
+<br>
+define i32 @f5() nounwind {<br>
+entry:<br>
+ %0 = load i32, i32* @j, align 4<br>
+ %1 = load i32, i32* @k, align 4<br>
+ %add = add nsw i32 %0, %1<br>
+ ret i32 %add<br>
+}<br>
+<br>
+; X32-LABEL: f5:<br>
+; X32: movl __emutls_v.j@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X32-NEXT: movl (%eax), %esi<br>
+; X32-NEXT: movl __emutls_v.k@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X32-NEXT: addl (%eax), %esi<br>
+; X32-NEXT: movl %esi, %eax<br>
+<br>
+; X64-LABEL: f5:<br>
+; X64: movq __emutls_v.j@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+; X64-NEXT: movl (%rax), %ebx<br>
+; X64-NEXT: movq __emutls_v.k@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+; X64-NEXT: addl (%rax), %ebx<br>
+; X64-NEXT: movl %ebx, %eax<br>
+<br>
+;;;;; 32-bit targets<br>
+<br>
+; X32: .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.i:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.i<br>
+<br>
+; X32: .section .rodata,<br>
+; X32-LABEL: __emutls_t.i:<br>
+; X32-NEXT: .long 15<br>
+<br>
+; X32: .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.j:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.j<br>
+<br>
+; X32: .section .rodata,<br>
+; X32-LABEL: __emutls_t.j:<br>
+; X32-NEXT: .long 42<br>
+<br>
+; X32: .data<br>
+; X32-LABEL: __emutls_v.k:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 8<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long 0<br>
+<br>
+; X32-NOT: __emutls_t.k:<br>
+<br>
+;;;;; 64-bit targets<br>
+<br>
+; X64: .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.i:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.i<br>
+<br>
+; X64: .section .rodata,<br>
+; X64-LABEL: __emutls_t.i:<br>
+; X64-NEXT: .long 15<br>
+<br>
+; X64: .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.j:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.j<br>
+<br>
+; X64: .section .rodata,<br>
+; X64-LABEL: __emutls_t.j:<br>
+; X64-NEXT: .long 42<br>
+<br>
+; X64: .data<br>
+; X64-LABEL: __emutls_v.k:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 8<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad 0<br>
+<br>
+; X64-NOT: __emutls_t.k:<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/emutls-pie.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_emutls-2Dpie.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=qwOvMs5El8RigZAnMSHjDxyKlr_v9ch3akkDZLBaY4A&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/emutls-pie.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/emutls-pie.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/emutls-pie.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,131 @@<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -enable-pie \<br>
+; RUN: | FileCheck -check-prefix=X32 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie \<br>
+; RUN: | FileCheck -check-prefix=X64 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-android -relocation-model=pic -enable-pie \<br>
+; RUN: | FileCheck -check-prefix=X32 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic -enable-pie \<br>
+; RUN: | FileCheck -check-prefix=X64 %s<br>
+<br>
+; Use my_emutls_get_address like __emutls_get_address.<br>
+@my_emutls_v_xyz = external global i8*, align 4<br>
+declare i8* @my_emutls_get_address(i8*)<br>
+<br>
+define i32 @my_get_xyz() {<br>
+; X32-LABEL: my_get_xyz:<br>
+; X32: movl my_emutls_v_xyz@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll my_emutls_get_address@PLT<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $8, %esp<br>
+; X32-NEXT: popl %ebx<br>
+; X32-NEXT: retl<br>
+; X64-LABEL: my_get_xyz:<br>
+; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq my_emutls_get_address@PLT<br>
+; X64-NEXT: movl (%rax), %eax<br>
+; X64-NEXT: popq %rdx<br>
+; X64-NEXT: retq<br>
+<br>
+entry:<br>
+ %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))<br>
+ %0 = bitcast i8* %call to i32*<br>
+ %1 = load i32, i32* %0, align 4<br>
+ ret i32 %1<br>
+}<br>
+<br>
+@i = thread_local global i32 15<br>
+@i2 = external thread_local global i32<br>
+<br>
+define i32 @f1() {<br>
+; X32-LABEL: f1:<br>
+; X32: movl __emutls_v.i@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $8, %esp<br>
+; X32-NEXT: popl %ebx<br>
+; X32-NEXT: retl<br>
+; X64-LABEL: f1:<br>
+; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+; X64-NEXT: movl (%rax), %eax<br>
+; X64-NEXT: popq %rdx<br>
+; X64-NEXT: retq<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f2() {<br>
+; X32-LABEL: f2:<br>
+; X32: movl __emutls_v.i@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X64-LABEL: f2:<br>
+; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+<br>
+entry:<br>
+ ret i32* @i<br>
+}<br>
+<br>
+define i32 @f3() {<br>
+; X32-LABEL: f3:<br>
+; X32: movl __emutls_v.i2@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X64-LABEL: f3:<br>
+; X64: movq __emutls_v.i2@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i2<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f4() {<br>
+; X32-LABEL: f4:<br>
+; X32: movl __emutls_v.i2@GOT(%ebx), %eax<br>
+; X32-NEXT: movl %eax, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address@PLT<br>
+; X64-LABEL: f4:<br>
+; X64: movq __emutls_v.i2@GOTPCREL(%rip), %rdi<br>
+; X64-NEXT: callq __emutls_get_address@PLT<br>
+<br>
+entry:<br>
+ ret i32* @i2<br>
+}<br>
+<br>
+;;;;; 32-bit targets<br>
+<br>
+; X32: .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.i:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.i<br>
+<br>
+; X32: .section .rodata,<br>
+; X32-LABEL: __emutls_t.i:<br>
+; X32-NEXT: .long 15<br>
+<br>
+; X32-NOT: __emutls_v.i2<br>
+; X32-NOT: __emutls_t.i2<br>
+<br>
+;;;;; 64-bit targets<br>
+<br>
+; X64: .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.i:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.i<br>
+<br>
+; X64: .section .rodata,<br>
+; X64-LABEL: __emutls_t.i:<br>
+; X64-NEXT: .long 15<br>
+<br>
+; X64-NOT: __emutls_v.i2<br>
+; X64-NOT: __emutls_t.i2<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/emutls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_emutls.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=MXtkw4O_o9KvRvZvpHVLVHQVhfxiJpO1AOyUSoEfBDQ&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/emutls.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/emutls.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/emutls.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,347 @@<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu | FileCheck -check-prefix=X32 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86-linux-android | FileCheck -check-prefix=X32 %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s<br>
+<br>
+; Copied from tls.ll; emulated TLS model is not implemented<br>
+; for *-pc-win32 and *-pc-winows targets yet.<br>
+<br>
+; Use my_emutls_get_address like __emutls_get_address.<br>
+@my_emutls_v_xyz = external global i8*, align 4<br>
+declare i8* @my_emutls_get_address(i8*)<br>
+<br>
+define i32 @my_get_xyz() {<br>
+; X32-LABEL: my_get_xyz:<br>
+; X32: movl $my_emutls_v_xyz, (%esp)<br>
+; X32-NEXT: calll my_emutls_get_address<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+; X64-LABEL: my_get_xyz:<br>
+; X64: movl $my_emutls_v_xyz, %edi<br>
+; X64-NEXT: callq my_emutls_get_address<br>
+; X64-NEXT: movl (%rax), %eax<br>
+; X64-NEXT: popq %rdx<br>
+; X64-NEXT: retq<br>
+<br>
+entry:<br>
+ %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))<br>
+ %0 = bitcast i8* %call to i32*<br>
+ %1 = load i32, i32* %0, align 4<br>
+ ret i32 %1<br>
+}<br>
+<br>
+@i1 = thread_local global i32 15<br>
+@i2 = external thread_local global i32<br>
+@i3 = internal thread_local global i32 15<br>
+@i4 = hidden thread_local global i32 15<br>
+@i5 = external hidden thread_local global i32<br>
+@s1 = thread_local global i16 15<br>
+@b1 = thread_local global i8 0<br>
+<br>
+define i32 @f1() {<br>
+; X32-LABEL: f1:<br>
+; X32: movl $__emutls_v.i1, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+; X64-LABEL: f1:<br>
+; X64: movl $__emutls_v.i1, %edi<br>
+; X64-NEXT: callq __emutls_get_address<br>
+; X64-NEXT: movl (%rax), %eax<br>
+; X64-NEXT: popq %rdx<br>
+; X64-NEXT: retq<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i1<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f2() {<br>
+; X32-LABEL: f2:<br>
+; X32: movl $__emutls_v.i1, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+; X64-LABEL: f2:<br>
+; X64: movl $__emutls_v.i1, %edi<br>
+; X64-NEXT: callq __emutls_get_address<br>
+; X64-NEXT: popq %rdx<br>
+; X64-NEXT: retq<br>
+<br>
+entry:<br>
+ ret i32* @i1<br>
+}<br>
+<br>
+define i32 @f3() nounwind {<br>
+; X32-LABEL: f3:<br>
+; X32: movl $__emutls_v.i2, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i2<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f4() {<br>
+; X32-LABEL: f4:<br>
+; X32: movl $__emutls_v.i2, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ ret i32* @i2<br>
+}<br>
+<br>
+define i32 @f5() nounwind {<br>
+; X32-LABEL: f5:<br>
+; X32: movl $__emutls_v.i3, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i3<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f6() {<br>
+; X32-LABEL: f6:<br>
+; X32: movl $__emutls_v.i3, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ ret i32* @i3<br>
+}<br>
+<br>
+define i32 @f7() {<br>
+; X32-LABEL: f7:<br>
+; X32: movl $__emutls_v.i4, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i4<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f8() {<br>
+; X32-LABEL: f8:<br>
+; X32: movl $__emutls_v.i4, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ ret i32* @i4<br>
+}<br>
+<br>
+define i32 @f9() {<br>
+; X32-LABEL: f9:<br>
+; X32: movl $__emutls_v.i5, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i32, i32* @i5<br>
+ ret i32 %tmp1<br>
+}<br>
+<br>
+define i32* @f10() {<br>
+; X32-LABEL: f10:<br>
+; X32: movl $__emutls_v.i5, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ ret i32* @i5<br>
+}<br>
+<br>
+define i16 @f11() {<br>
+; X32-LABEL: f11:<br>
+; X32: movl $__emutls_v.s1, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movzwl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i16, i16* @s1<br>
+ ret i16 %tmp1<br>
+}<br>
+<br>
+define i32 @f12() {<br>
+; X32-LABEL: f12:<br>
+; X32: movl $__emutls_v.s1, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movswl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i16, i16* @s1<br>
+ %tmp2 = sext i16 %tmp1 to i32<br>
+ ret i32 %tmp2<br>
+}<br>
+<br>
+define i8 @f13() {<br>
+; X32-LABEL: f13:<br>
+; X32: movl $__emutls_v.b1, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movb (%eax), %al<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i8, i8* @b1<br>
+ ret i8 %tmp1<br>
+}<br>
+<br>
+define i32 @f14() {<br>
+; X32-LABEL: f14:<br>
+; X32: movl $__emutls_v.b1, (%esp)<br>
+; X32-NEXT: calll __emutls_get_address<br>
+; X32-NEXT: movsbl (%eax), %eax<br>
+; X32-NEXT: addl $12, %esp<br>
+; X32-NEXT: retl<br>
+<br>
+entry:<br>
+ %tmp1 = load i8, i8* @b1<br>
+ %tmp2 = sext i8 %tmp1 to i32<br>
+ ret i32 %tmp2<br>
+}<br>
+<br>
+;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t.<br>
+<br>
+; X32 .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.i1:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.i1<br>
+<br>
+; X32 .section .rodata,<br>
+; X32-LABEL: __emutls_t.i1:<br>
+; X32-NEXT: .long 15<br>
+<br>
+; X32-NOT: __emutls_v.i2<br>
+<br>
+; X32 .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.i3:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.i3<br>
+<br>
+; X32 .section .rodata,<br>
+; X32-LABEL: __emutls_t.i3:<br>
+; X32-NEXT: .long 15<br>
+<br>
+; X32 .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.i4:<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 4<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.i4<br>
+<br>
+; X32 .section .rodata,<br>
+; X32-LABEL: __emutls_t.i4:<br>
+; X32-NEXT: .long 15<br>
+<br>
+; X32-NOT: __emutls_v.i5:<br>
+; X32 .hidden __emutls_v.i5<br>
+; X32-NOT: __emutls_v.i5:<br>
+<br>
+; X32 .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.s1:<br>
+; X32-NEXT: .long 2<br>
+; X32-NEXT: .long 2<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long __emutls_t.s1<br>
+<br>
+; X32 .section .rodata,<br>
+; X32-LABEL: __emutls_t.s1:<br>
+; X32-NEXT: .short 15<br>
+<br>
+; X32 .section .data.rel.local,<br>
+; X32-LABEL: __emutls_v.b1:<br>
+; X32-NEXT: .long 1<br>
+; X32-NEXT: .long 1<br>
+; X32-NEXT: .long 0<br>
+; X32-NEXT: .long 0<br>
+<br>
+; X32-NOT: __emutls_t.b1<br>
+<br>
+;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t.<br>
+<br>
+; X64 .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.i1:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.i1<br>
+<br>
+; X64 .section .rodata,<br>
+; X64-LABEL: __emutls_t.i1:<br>
+; X64-NEXT: .long 15<br>
+<br>
+; X64-NOT: __emutls_v.i2<br>
+<br>
+; X64 .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.i3:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.i3<br>
+<br>
+; X64 .section .rodata,<br>
+; X64-LABEL: __emutls_t.i3:<br>
+; X64-NEXT: .long 15<br>
+<br>
+; X64 .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.i4:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.i4<br>
+<br>
+; X64 .section .rodata,<br>
+; X64-LABEL: __emutls_t.i4:<br>
+; X64-NEXT: .long 15<br>
+<br>
+; X64-NOT: __emutls_v.i5:<br>
+; X64 .hidden __emutls_v.i5<br>
+; X64-NOT: __emutls_v.i5:<br>
+<br>
+; X64 .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.s1:<br>
+; X64-NEXT: .quad 2<br>
+; X64-NEXT: .quad 2<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.s1<br>
+<br>
+; X64 .section .rodata,<br>
+; X64-LABEL: __emutls_t.s1:<br>
+; X64-NEXT: .short 15<br>
+<br>
+; X64 .section .data.rel.local,<br>
+; X64-LABEL: __emutls_v.b1:<br>
+; X64-NEXT: .quad 1<br>
+; X64-NEXT: .quad 1<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad 0<br>
+<br>
+; X64-NOT: __emutls_t.b1<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/fast-isel-emutls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_fast-2Disel-2Demutls.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=IWVedXyODJD_fs4MxtGmtn2ibhgNKDex96QgbjYworQ&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-emutls.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/fast-isel-emutls.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/fast-isel-emutls.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,48 @@<br>
+; RUN: llc < %s -emulated-tls -march=x86 -relocation-model=pic -mtriple=i686-unknown-linux-gnu -fast-isel | FileCheck %s<br>
+; PR3654<br>
+<br>
+@v = thread_local global i32 0<br>
+define i32 @f() nounwind {<br>
+entry:<br>
+ %t = load i32, i32* @v<br>
+ %s = add i32 %t, 1<br>
+ ret i32 %s<br>
+}<br>
+<br>
+; CHECK-LABEL: f:<br>
+; CHECK: movl __emutls_v.v@GOT(%ebx), %eax<br>
+; CHECK-NEXT: movl %eax, (%esp)<br>
+; CHECK-NEXT: calll __emutls_get_address@PLT<br>
+; CHECK-NEXT: movl (%eax), %eax<br>
+<br>
+@alias = internal alias i32* @v<br>
+define i32 @f_alias() nounwind {<br>
+entry:<br>
+ %t = load i32, i32* @v<br>
+ %s = add i32 %t, 1<br>
+ ret i32 %s<br>
+}<br>
+<br>
+; CHECK-LABEL: f_alias:<br>
+; CHECK: movl __emutls_v.v@GOT(%ebx), %eax<br>
+; CHECK-NEXT: movl %eax, (%esp)<br>
+; CHECK-NEXT: calll __emutls_get_address@PLT<br>
+; CHECK-NEXT: movl (%eax), %eax<br>
+<br>
+; Use my_emutls_get_address like __emutls_get_address.<br>
+@my_emutls_v_xyz = external global i8*, align 4<br>
+declare i8* @my_emutls_get_address(i8*)<br>
+<br>
+define i32 @my_get_xyz() {<br>
+entry:<br>
+ %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))<br>
+ %0 = bitcast i8* %call to i32*<br>
+ %1 = load i32, i32* %0, align 4<br>
+ ret i32 %1<br>
+}<br>
+<br>
+; CHECK-LABEL: my_get_xyz:<br>
+; CHECK: movl my_emutls_v_xyz@GOT(%ebx), %eax<br>
+; CHECK-NEXT: movl %eax, (%esp)<br>
+; CHECK-NEXT: calll my_emutls_get_address@PLT<br>
+; CHECK-NEXT: movl (%eax), %eax<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/tls-android-negative.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_tls-2Dandroid-2Dnegative.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=b3nZV7PIHgGP6zlXyXMhdFOJxQT2GW9KFVKRuTjImpc&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls-android-negative.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/tls-android-negative.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/tls-android-negative.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,65 @@<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s<br>
+<br>
+; Make sure that some symboles are not emitted in emulated TLS model.<br>
+<br>
+@external_x = external thread_local global i32<br>
+@external_y = thread_local global i32 7<br>
+@internal_y = internal thread_local global i32 9<br>
+@internal_y0 = internal thread_local global i32 0<br>
+<br>
+define i32* @get_external_x() {<br>
+entry:<br>
+ ret i32* @external_x<br>
+}<br>
+<br>
+define i32* @get_external_y() {<br>
+entry:<br>
+ ret i32* @external_y<br>
+}<br>
+<br>
+define i32* @get_internal_y() {<br>
+entry:<br>
+ ret i32* @internal_y<br>
+}<br>
+<br>
+define i32* @get_internal_y0() {<br>
+entry:<br>
+ ret i32* @internal_y0<br>
+}<br>
+<br>
+; no direct access to emulated TLS variables.<br>
+; no definition of emulated TLS variables.<br>
+; no initializer for external TLS variables, __emutls_t.external_x<br>
+; no initializer for 0-initialized TLS variables, __emutls_t.internal_y0<br>
+; not global linkage for __emutls_t.external_y<br>
+<br>
+; CHECK-NOT: external_x@TLS<br>
+; CHECK-NOT: external_y@TLS<br>
+; CHECK-NOT: internal_y@TLS<br>
+; CHECK-NOT: .size external_x<br>
+; CHECK-NOT: .size external_y<br>
+; CHECK-NOT: .size internal_y<br>
+; CHECK-NOT: .size internal_y0<br>
+; CHECK-NOT: __emutls_v.external_x:<br>
+; CHECK-NOT: __emutls_t.external_x:<br>
+; CHECK-NOT: __emutls_t.internal_y0:<br>
+; CHECK-NOT: global __emutls_t.external_y<br>
+; CHECK-NOT: global __emutls_v.internal_y<br>
+; CHECK-NOT: global __emutls_v.internal_y0<br>
+<br>
+; CHECK: __emutls_t.external_y<br>
+<br>
+; CHECK-NOT: external_x@TLS<br>
+; CHECK-NOT: external_y@TLS<br>
+; CHECK-NOT: internal_y@TLS<br>
+; CHECK-NOT: .size external_x<br>
+; CHECK-NOT: .size external_y<br>
+; CHECK-NOT: .size internal_y<br>
+; CHECK-NOT: .size internal_y0<br>
+; CHECK-NOT: __emutls_v.external_x:<br>
+; CHECK-NOT: __emutls_t.external_x:<br>
+; CHECK-NOT: __emutls_t.internal_y0:<br>
+; CHECK-NOT: global __emutls_t.external_y<br>
+; CHECK-NOT: global __emutls_v.internal_y<br>
+; CHECK-NOT: global __emutls_v.internal_y0<br>
<br>
Added: llvm/trunk/test/CodeGen/X86/tls-android.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_tls-2Dandroid.ll-3Frev-3D243438-26view-3Dauto&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=C1oSyGjDp4qf4Pj7nSzqsVPN6qkqkGGGoYHu2coOB-s&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls-android.ll?rev=243438&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/tls-android.ll (added)<br>
+++ llvm/trunk/test/CodeGen/X86/tls-android.ll Tue Jul 28 11:24:05 2015<br>
@@ -0,0 +1,89 @@<br>
+; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s<br>
+; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s<br>
+<br>
+; Make sure that TLS symboles are emitted in expected order.<br>
+<br>
+@external_x = external thread_local global i32<br>
+@external_y = thread_local global i32 7<br>
+@internal_y = internal thread_local global i32 9<br>
+<br>
+define i32* @get_external_x() {<br>
+entry:<br>
+ ret i32* @external_x<br>
+}<br>
+<br>
+define i32* @get_external_y() {<br>
+entry:<br>
+ ret i32* @external_y<br>
+}<br>
+<br>
+define i32* @get_internal_y() {<br>
+entry:<br>
+ ret i32* @internal_y<br>
+}<br>
+<br>
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32-bit mode<br>
+; CHECK-LABEL: get_external_x:<br>
+; CHECK: __emutls_v.external_x<br>
+; CHECK: __emutls_get_address<br>
+<br>
+; CHECK-LABEL: get_external_y:<br>
+; CHECK: __emutls_v.external_y<br>
+; CHECK: __emutls_get_address<br>
+<br>
+; CHECK-LABEL: get_internal_y:<br>
+; CHECK: __emutls_v.internal_y<br>
+; CHECK: __emutls_get_address<br>
+<br>
+; CHECK-NOT: __emutls_v.external_x:<br>
+<br>
+; CHECK: .align 4<br>
+; CHECK-LABEL: __emutls_v.external_y:<br>
+; CHECK-NEXT: .long 4<br>
+; CHECK-NEXT: .long 4<br>
+; CHECK-NEXT: .long 0<br>
+; CHECK-NEXT: .long __emutls_t.external_y<br>
+; CHECK-LABEL: __emutls_t.external_y:<br>
+; CHECK-NEXT: .long 7<br>
+<br>
+; CHECK: .align 4<br>
+; CHECK-LABEL: __emutls_v.internal_y:<br>
+; CHECK-NEXT: .long 4<br>
+; CHECK-NEXT: .long 4<br>
+; CHECK-NEXT: .long 0<br>
+; CHECK-NEXT: .long __emutls_t.internal_y<br>
+; CHECK-LABEL: __emutls_t.internal_y:<br>
+; CHECK-NEXT: .long 9<br>
+<br>
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64-bit mode<br>
+; X64-LABEL: get_external_x:<br>
+; X64: __emutls_v.external_x<br>
+; X64: __emutls_get_address<br>
+<br>
+; X64-LABEL: get_external_y:<br>
+; X64: __emutls_v.external_y<br>
+; X64: __emutls_get_address<br>
+<br>
+; X64-LABEL: get_internal_y:<br>
+; X64: __emutls_v.internal_y<br>
+; X64: __emutls_get_address<br>
+<br>
+; X64-NOT: __emutls_v.external_x:<br>
+<br>
+; X64: .align 8<br>
+; X64-LABEL: __emutls_v.external_y:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.external_y<br>
+; X64-LABEL: __emutls_t.external_y:<br>
+; X64-NEXT: .long 7<br>
+<br>
+; X64: .align 8<br>
+; X64-LABEL: __emutls_v.internal_y:<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 4<br>
+; X64-NEXT: .quad 0<br>
+; X64-NEXT: .quad __emutls_t.internal_y<br>
+; X64-LABEL: __emutls_t.internal_y:<br>
+; X64-NEXT: .long 9<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/tls-models.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_CodeGen_X86_tls-2Dmodels.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=oIIfTCVC78doog0grhu48sYb8vwSknpQ0TnZsVDSbH8&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls-models.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/tls-models.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/tls-models.ll Tue Jul 28 11:24:05 2015<br>
@@ -18,6 +18,8 @@<br>
@external_le = external thread_local(localexec) global i32<br>
@internal_le = internal thread_local(localexec) global i32 42<br>
<br>
+; See test cases for emulated model in emutls.ll, emutls-pic.ll and emutls-pie.ll.<br>
+<br>
; ----- no model specified -----<br>
<br>
define i32* @f1() {<br>
<br>
Modified: llvm/trunk/test/DebugInfo/ARM/tls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_DebugInfo_ARM_tls.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=wVbk9cN0aN_2OJo9iNXzJuZZQ5MD6lVVoCtwisgsN0s&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/ARM/tls.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/ARM/tls.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/ARM/tls.ll Tue Jul 28 11:24:05 2015<br>
@@ -1,5 +1,8 @@<br>
-; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi < %s | FileCheck %s<br>
-;<br>
+; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi < %s \<br>
+; RUN: | FileCheck %s --check-prefix=CHECK<br>
+; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi -emulated-tls < %s \<br>
+; RUN: | FileCheck %s --check-prefix=EMU<br>
+<br>
; Generated with clang with source<br>
; __thread int x;<br>
<br>
@@ -16,6 +19,9 @@<br>
; The debug relocation of the address of the tls variable<br>
; CHECK: .long x(tlsldo)<br>
<br>
+; TODO: Add expected output for -emulated-tls tests.<br>
+; EMU-NOT: .long x(tlsldo)<br>
+<br>
!0 = !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !3, imports: !2)<br>
!1 = !DIFile(filename: "tls.c", directory: "/tmp")<br>
!2 = !{}<br>
<br>
Modified: llvm/trunk/test/DebugInfo/X86/tls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_DebugInfo_X86_tls.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=qVUKOsrkAYiga0RcrSQ53et9PKx8ge5SbYwAsAY7l5k&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/tls.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/X86/tls.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/X86/tls.ll Tue Jul 28 11:24:05 2015<br>
@@ -1,20 +1,30 @@<br>
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu \<br>
-; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=GNUOP %s<br>
+; RUN: | FileCheck --check-prefix=NOEMU --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=GNUOP %s<br>
<br>
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu \<br>
-; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-32 --check-prefix=GNUOP %s<br>
+; RUN: | FileCheck --check-prefix=NOEMU --check-prefix=SINGLE --check-prefix=SINGLE-32 --check-prefix=GNUOP %s<br>
<br>
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -split-dwarf=Enable \<br>
-; RUN: | FileCheck --check-prefix=FISSION --check-prefix=GNUOP %s<br>
+; RUN: | FileCheck --check-prefix=NOEMU --check-prefix=FISSION --check-prefix=GNUOP %s<br>
<br>
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-scei-ps4 \<br>
-; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=STDOP %s<br>
+; RUN: | FileCheck --check-prefix=NOEMU --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=STDOP %s<br>
<br>
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-apple-darwin \<br>
-; RUN: | FileCheck --check-prefix=DARWIN --check-prefix=STDOP %s<br>
+; RUN: | FileCheck --check-prefix=NOEMU --check-prefix=DARWIN --check-prefix=STDOP %s<br>
<br>
; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd \<br>
-; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=STDOP %s<br>
+; RUN: | FileCheck --check-prefix=NOEMU --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=STDOP %s<br>
+<br>
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -emulated-tls \<br>
+; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=EMUSINGLE-64 \<br>
+; RUN: --check-prefix=EMUGNUOP --check-prefix=EMU %s<br>
+<br>
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu -emulated-tls \<br>
+; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=EMUSINGLE-32 \<br>
+; RUN: --check-prefix=EMUGNUOP --check-prefix=EMU %s<br>
+<br>
+; TODO: Add expected output for -emulated-tls tests.<br>
<br>
; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use<br>
; that here instead of raw assembly printing<br>
<br>
Modified: llvm/trunk/test/Transforms/GlobalOpt/tls.ll<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_test_Transforms_GlobalOpt_tls.ll-3Frev-3D243438-26r1-3D243437-26r2-3D243438-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=xMoePMhGn7oDbNSBRC-EJFZYoX4vwfqLgRCuUczpKKc&s=pi9EVS7mhppYaXDjeOCEAaRgICO-AQn4jPmKn64iANw&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/tls.ll?rev=243438&r1=243437&r2=243438&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/GlobalOpt/tls.ll (original)<br>
+++ llvm/trunk/test/Transforms/GlobalOpt/tls.ll Tue Jul 28 11:24:05 2015<br>
@@ -1,4 +1,5 @@<br>
; RUN: opt < %s -globalopt -S | FileCheck %s<br>
+; RUN: opt -emulated-tls < %s -globalopt -S | FileCheck %s<br>
<br>
declare void @wait()<br>
declare void @signal()<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</blockquote></div><br></div>
</blockquote></div><br></div>