Index: include/llvm/ADT/Triple.h =================================================================== --- include/llvm/ADT/Triple.h +++ include/llvm/ADT/Triple.h @@ -665,6 +665,11 @@ return !isOSBinFormatMachO(); } + /// Tests whether the target uses emulated TLS as default. + bool hasDefaultEmulatedTLS() const { + return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment(); + } + /// @} /// @name Mutators /// @{ Index: include/llvm/CodeGen/CommandFlags.def =================================================================== --- include/llvm/CodeGen/CommandFlags.def +++ include/llvm/CodeGen/CommandFlags.def @@ -284,6 +284,7 @@ Options.FunctionSections = FunctionSections; Options.UniqueSectionNames = UniqueSectionNames; Options.EmulatedTLS = EmulatedTLS; + Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0; Options.ExceptionModel = ExceptionModel; Options.EmitStackSizeSection = EnableStackSizeSection; Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -172,6 +172,9 @@ bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const; + /// Returns true if this target uses emulated TLS. + bool useEmulatedTLS() const; + /// Returns the TLS model which should be used for the given global variable. TLSModel::Model getTLSModel(const GlobalValue *GV) const; Index: include/llvm/Target/TargetOptions.h =================================================================== --- include/llvm/Target/TargetOptions.h +++ include/llvm/Target/TargetOptions.h @@ -107,7 +107,8 @@ EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false), DisableIntegratedAS(false), RelaxELFRelocations(false), FunctionSections(false), DataSections(false), - UniqueSectionNames(true), TrapUnreachable(false), EmulatedTLS(false), + UniqueSectionNames(true), TrapUnreachable(false), + EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false), EmitStackSizeSection(false) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs @@ -216,6 +217,9 @@ /// function in the runtime library.. unsigned EmulatedTLS : 1; + /// Whether -emulated-tls or -no-emulated-tls is set. + unsigned ExplicitEmulatedTLS : 1; + /// This flag enables InterProcedural Register Allocation (IPRA). unsigned EnableIPRA : 1; Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -426,7 +426,7 @@ /// EmitGlobalVariable - Emit the specified global variable to the .s file. void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { - bool IsEmuTLSVar = TM.Options.EmulatedTLS && GV->isThreadLocal(); + bool IsEmuTLSVar = TM.useEmulatedTLS() && GV->isThreadLocal(); assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) && "No emulated TLS variables in the common section"); Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -197,7 +197,7 @@ if (Global) { const MCSymbol *Sym = Asm->getSymbol(Global); if (Global->isThreadLocal()) { - if (Asm->TM.Options.EmulatedTLS) { + if (Asm->TM.useEmulatedTLS()) { // TODO: add debug info for emulated thread local mode. } else { // FIXME: Make this work with -gsplit-dwarf. Index: lib/CodeGen/LowerEmuTLS.cpp =================================================================== --- lib/CodeGen/LowerEmuTLS.cpp +++ lib/CodeGen/LowerEmuTLS.cpp @@ -68,7 +68,7 @@ return false; auto &TM = TPC->getTM(); - if (!TM.Options.EmulatedTLS) + if (!TM.useEmulatedTLS()) return false; bool Changed = false; Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -745,7 +745,7 @@ } bool TargetPassConfig::addISelPasses() { - if (TM->Options.EmulatedTLS) + if (TM->useEmulatedTLS()) addPass(createLowerEmuTLSPass()); addPass(createPreISelIntrinsicLoweringPass()); Index: lib/ExecutionEngine/TargetSelect.cpp =================================================================== --- lib/ExecutionEngine/TargetSelect.cpp +++ lib/ExecutionEngine/TargetSelect.cpp @@ -97,6 +97,8 @@ Options, RelocModel, CMModel, OptLevel, /*JIT*/ true); Target->Options.EmulatedTLS = EmulatedTLS; + Target->Options.ExplicitEmulatedTLS = true; + assert(Target && "Could not allocate target machine!"); return Target; } Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3973,7 +3973,7 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { const GlobalAddressSDNode *GA = cast(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); if (Subtarget->isTargetDarwin()) Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -3004,7 +3004,7 @@ SDValue ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { GlobalAddressSDNode *GA = cast(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); if (Subtarget->isTargetDarwin()) Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -2073,7 +2073,7 @@ // Local Exec TLS Model. GlobalAddressSDNode *GA = cast(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); SDLoc DL(GA); Index: lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- lib/Target/PowerPC/PPCISelLowering.cpp +++ lib/Target/PowerPC/PPCISelLowering.cpp @@ -2571,7 +2571,7 @@ // large models could be added if users need it, at the cost of // additional complexity. GlobalAddressSDNode *GA = cast(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); SDLoc dl(GA); Index: lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- lib/Target/Sparc/SparcISelLowering.cpp +++ lib/Target/Sparc/SparcISelLowering.cpp @@ -2036,7 +2036,7 @@ SelectionDAG &DAG) const { GlobalAddressSDNode *GA = cast(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); SDLoc DL(GA); Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -2663,7 +2663,7 @@ SDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node, SelectionDAG &DAG) const { - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(Node, DAG); SDLoc DL(Node); const GlobalValue *GV = Node->getGlobal(); Index: lib/Target/TargetMachine.cpp =================================================================== --- lib/Target/TargetMachine.cpp +++ lib/Target/TargetMachine.cpp @@ -185,6 +185,14 @@ return false; } +bool TargetMachine::useEmulatedTLS() const { + // Returns Options.EmulatedTLS if the -emulated-tls or -no-emulated-tls + // was specified explicitly; otherwise uses target triple to decide default. + if (Options.ExplicitEmulatedTLS) + return Options.EmulatedTLS; + return getTargetTriple().hasDefaultEmulatedTLS(); +} + TLSModel::Model TargetMachine::getTLSModel(const GlobalValue *GV) const { bool IsPIE = GV->getParent()->getPIELevel() != PIELevel::Default; Reloc::Model RM = getRelocationModel(); Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -15615,7 +15615,7 @@ GlobalAddressSDNode *GA = cast(Op); - if (DAG.getTarget().Options.EmulatedTLS) + if (DAG.getTarget().useEmulatedTLS()) return LowerToTLSEmulatedModel(GA, DAG); const GlobalValue *GV = GA->getGlobal(); Index: test/CodeGen/AArch64/emutls.ll =================================================================== --- test/CodeGen/AArch64/emutls.ll +++ test/CodeGen/AArch64/emutls.ll @@ -1,5 +1,7 @@ ; RUN: llc -emulated-tls -mtriple=aarch64-linux-android \ ; RUN: -relocation-model=pic -disable-fp-elim < %s | FileCheck -check-prefix=ARM64 %s +; RUN: llc -mtriple=aarch64-linux-android \ +; RUN: -relocation-model=pic -disable-fp-elim < %s | FileCheck -check-prefix=ARM64 %s ; Copied from X86/emutls.ll Index: test/CodeGen/AArch64/emutls_generic.ll =================================================================== --- test/CodeGen/AArch64/emutls_generic.ll +++ test/CodeGen/AArch64/emutls_generic.ll @@ -9,6 +9,18 @@ ; RUN: llc < %s -emulated-tls -mtriple=aarch64-apple-darwin -O3 \ ; RUN: | FileCheck -check-prefix=DARWIN %s +; RUN: llc < %s -mtriple=aarch64-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -mtriple=aarch64-linux-android -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; RUN: llc < %s -mtriple=aarch64-linux-android -O3 \ +; RUN: | FileCheck -check-prefix=ARM_64 %s +; aarch64-windows-gnu needs explicit -emulated-tls +; RUN: llc < %s -mtriple=aarch64-apple-darwin -O3 \ +; RUN: | FileCheck -check-prefix=NoEMU %s + +; NoEMU-NOT: __emutls + ; Make sure that TLS symbols are emitted in expected order. @external_x = external thread_local global i32, align 8 Index: test/CodeGen/ARM/emutls.ll =================================================================== --- test/CodeGen/ARM/emutls.ll +++ test/CodeGen/ARM/emutls.ll @@ -1,5 +1,7 @@ ; RUN: llc -emulated-tls -mtriple=arm-linux-android \ ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s +; RUN: llc -mtriple=arm-linux-android \ +; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s ; Copied from X86/emutls.ll Index: test/CodeGen/ARM/emutls_generic.ll =================================================================== --- test/CodeGen/ARM/emutls_generic.ll +++ test/CodeGen/ARM/emutls_generic.ll @@ -11,6 +11,17 @@ ; RUN: llc < %s -emulated-tls -mtriple=thumbv7-windows-gnu -O3 \ ; RUN: | FileCheck -check-prefix=WIN %s +; RUN: llc < %s -mtriple=arm-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_32 %s +; RUN: llc < %s -mtriple=arm-linux-androidabi -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=ARM_32 %s +; RUN: llc < %s -mtriple=arm-linux-androidabi -relocation-model=pic -O3 \ +; RUN: | FileCheck -check-prefix=ARM_32 %s +; RUN: llc < %s -mtriple=arm-linux-androidabi -O3 \ +; RUN: | FileCheck -check-prefix=ARM_32 %s +; arm-apple-darwin must use -emulated-tls +; windows must use -emulated-tls + ; Make sure that TLS symbols are emitted in expected order. @external_x = external thread_local global i32, align 8 Index: test/CodeGen/Mips/emutls_generic.ll =================================================================== --- test/CodeGen/Mips/emutls_generic.ll +++ test/CodeGen/Mips/emutls_generic.ll @@ -3,6 +3,11 @@ ; RUN: llc < %s -emulated-tls -mtriple=mips64el-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=MIPS_64 %s +; RUN: llc < %s -mtriple=mipsel-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=MIPS_32 %s +; RUN: llc < %s -mtriple=mips64el-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=MIPS_64 %s + ; Make sure that TLS symbols are emitted in expected order. @external_x = external thread_local global i32, align 8 Index: test/CodeGen/PowerPC/emutls_generic.ll =================================================================== --- test/CodeGen/PowerPC/emutls_generic.ll +++ test/CodeGen/PowerPC/emutls_generic.ll @@ -3,6 +3,13 @@ ; RUN: llc < %s -emulated-tls -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck %s +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=NoEMU %s + +; NoEMU-NOT: __emutls + ; Make sure that TLS symbols are emitted in expected order. @external_x = external thread_local global i32, align 8 Index: test/CodeGen/X86/emutls-pic.ll =================================================================== --- test/CodeGen/X86/emutls-pic.ll +++ test/CodeGen/X86/emutls-pic.ll @@ -3,6 +3,13 @@ ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X32 %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X32 %s +; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s + +; NoEMU-NOT: __emutls + ; Use my_emutls_get_address like __emutls_get_address. @my_emutls_v_xyz = external global i8*, align 4 declare i8* @my_emutls_get_address(i8*) Index: test/CodeGen/X86/emutls-pie.ll =================================================================== --- test/CodeGen/X86/emutls-pie.ll +++ test/CodeGen/X86/emutls-pie.ll @@ -7,6 +7,17 @@ ; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X32 %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X64 %s + +; NoEMU-NOT: __emutls + ; Use my_emutls_get_address like __emutls_get_address. @my_emutls_v_xyz = external global i8*, align 4 declare i8* @my_emutls_get_address(i8*) Index: test/CodeGen/X86/emutls.ll =================================================================== --- test/CodeGen/X86/emutls.ll +++ test/CodeGen/X86/emutls.ll @@ -3,8 +3,15 @@ ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android | FileCheck -check-prefix=X32 %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=NoEMU %s +; RUN: llc < %s -mtriple=i386-linux-android | FileCheck -check-prefix=X32 %s +; RUN: llc < %s -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s + ; Copied from tls.ll; emulated TLS model is not implemented -; for *-pc-win32 and *-pc-winows targets yet. +; for *-pc-win32 and *-pc-windows targets yet. + +; NoEMU-NOT: __emutls ; Use my_emutls_get_address like __emutls_get_address. @my_emutls_v_xyz = external global i8*, align 4 Index: test/CodeGen/X86/emutls_generic.ll =================================================================== --- test/CodeGen/X86/emutls_generic.ll +++ test/CodeGen/X86/emutls_generic.ll @@ -7,6 +7,17 @@ ; RUN: llc < %s -emulated-tls -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_32 %s +; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X86_64 %s +; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=NoEMU %s + +; NoEMU-NOT: __emutls + ; Make sure that TLS symbols are emitted in expected order. @external_x = external thread_local global i32, align 8 Index: test/CodeGen/X86/fast-isel-emutls.ll =================================================================== --- test/CodeGen/X86/fast-isel-emutls.ll +++ test/CodeGen/X86/fast-isel-emutls.ll @@ -1,6 +1,10 @@ ; RUN: llc < %s -emulated-tls -relocation-model=pic -mtriple=i686-unknown-linux-gnu -fast-isel | FileCheck %s +; RUN: llc < %s -relocation-model=pic -mtriple=i686-unknown-linux-gnu -fast-isel \ +; RUN: | FileCheck -check-prefix=NoEMU %s ; PR3654 +; NoEMU-NOT: __emutls + @v = thread_local global i32 0 define i32 @f() nounwind { entry: Index: test/CodeGen/X86/global-access-pie-copyrelocs.ll =================================================================== --- test/CodeGen/X86/global-access-pie-copyrelocs.ll +++ test/CodeGen/X86/global-access-pie-copyrelocs.ll @@ -1,8 +1,13 @@ -; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -pie-copy-relocations \ +; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -pie-copy-relocations \ ; RUN: | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -pie-copy-relocations \ ; RUN: | FileCheck -check-prefix=X32 %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -pie-copy-relocations \ +; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -pie-copy-relocations \ +; RUN: | FileCheck -check-prefix=X32 %s + ; External Linkage @a = global i32 0, align 4 Index: test/CodeGen/X86/global-access-pie.ll =================================================================== --- test/CodeGen/X86/global-access-pie.ll +++ test/CodeGen/X86/global-access-pie.ll @@ -1,8 +1,13 @@ -; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic \ +; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X64 %s ; RUN: llc < %s -emulated-tls -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \ ; RUN: | FileCheck -check-prefix=X32 %s +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic \ +; RUN: | FileCheck -check-prefix=X32 %s + ; External Linkage @a = global i32 0, align 4 Index: test/CodeGen/X86/tls-android-negative.ll =================================================================== --- test/CodeGen/X86/tls-android-negative.ll +++ test/CodeGen/X86/tls-android-negative.ll @@ -1,6 +1,9 @@ ; RUN: llc < %s -emulated-tls -mtriple=i686-linux-android -relocation-model=pic | FileCheck %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s +; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s + ; Make sure that some symboles are not emitted in emulated TLS model. @external_x = external thread_local global i32 Index: test/CodeGen/X86/tls-android.ll =================================================================== --- test/CodeGen/X86/tls-android.ll +++ test/CodeGen/X86/tls-android.ll @@ -1,6 +1,9 @@ ; RUN: llc < %s -emulated-tls -mtriple=i686-linux-android -relocation-model=pic | FileCheck %s ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s +; RUN: llc < %s -mtriple=i686-linux-android -relocation-model=pic | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s + ; Make sure that TLS symboles are emitted in expected order. @external_x = external thread_local global i32