Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -1450,6 +1450,10 @@ ``noredzone`` This attribute indicates that the code generator should not use a red zone, even if the target-specific ABI normally permits it. +``indirect-tls-seg-refs`` + This attribute indicates that the code generator should not use + direct TLS access through segment registers, even if the + target-specific ABI normally permits it. ``noreturn`` This function attribute indicates that the function never returns normally. This produces undefined behavior at runtime if the Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp +++ lib/Target/X86/X86ISelDAGToDAG.cpp @@ -165,6 +165,9 @@ /// If true, selector should try to optimize for minimum code size. bool OptForMinSize; + /// Disable direct TLS access through segment registers + bool IndirectTlsSegRefs; + public: explicit X86DAGToDAGISel(X86TargetMachine &tm, CodeGenOpt::Level OptLevel) : SelectionDAGISel(tm, OptLevel), OptForSize(false), @@ -177,6 +180,8 @@ bool runOnMachineFunction(MachineFunction &MF) override { // Reset the subtarget each time through. Subtarget = &MF.getSubtarget(); + IndirectTlsSegRefs = MF.getFunction().hasFnAttribute( + "indirect-tls-seg-refs"); SelectionDAGISel::runOnMachineFunction(MF); return true; } @@ -979,6 +984,7 @@ // For more information see http://people.redhat.com/drepper/tls.pdf if (ConstantSDNode *C = dyn_cast(Address)) if (C->getSExtValue() == 0 && AM.Segment.getNode() == nullptr && + !IndirectTlsSegRefs && (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())) switch (N->getPointerInfo().getAddrSpace()) { Index: test/CodeGen/X86/tls.ll =================================================================== --- test/CodeGen/X86/tls.ll +++ test/CodeGen/X86/tls.ll @@ -453,3 +453,20 @@ ret i32* @i6 } + +define i32 @f17() #0 { +; X86_LINUX-LABEL: f17: +; X86_LINUX: movl %gs:0, %eax +; X86_LINUX-NEXT: movl i1@NTPOFF(%eax), %eax +; X86_LINUX-NEXT: ret +; X64_LINUX-LABEL: f17: +; X64_LINUX: movq %fs:0, %rax +; X64_LINUX-NEXT: movl i1@TPOFF(%rax), %eax +; X64_LINUX-NEXT: ret + +entry: + %tmp1 = load i32, i32* @i1 + ret i32 %tmp1 +} + +attributes #0 = { "indirect-tls-seg-refs" }