<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>