[llvm] r344723 - [X86] Support for the mno-tls-direct-seg-refs flag

Kristina Brooks via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 17 20:14:37 PDT 2018


Author: kristina
Date: Wed Oct 17 20:14:37 2018
New Revision: 344723

URL: http://llvm.org/viewvc/llvm-project?rev=344723&view=rev
Log:
[X86] Support for the mno-tls-direct-seg-refs flag

Allows to disable direct TLS segment access (%fs or %gs). GCC supports
a similar flag, it can be useful in some circumstances, e.g. when a thread
context block needs to be updated directly from user space. More info
and specific use cases: https://bugs.llvm.org/show_bug.cgi?id=16145

There is another revision for clang as well.
Related: D53102

All X86 CodeGen tests appear to pass:
```
[46/47] Running lit suite /SourceCache/llvm-trunk-8.0/test/CodeGen
Testing Time: 23.17s
  Expected Passes    : 3801
  Expected Failures  : 15
  Unsupported Tests  : 8021
```

Reviewed by: Craig Topper.

Patch by nruslan (Ruslan Nikolaev).

Differential Revision: https://reviews.llvm.org/D53103


Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/test/CodeGen/X86/tls.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=344723&r1=344722&r2=344723&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Wed Oct 17 20:14:37 2018
@@ -1450,6 +1450,10 @@ example:
 ``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

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=344723&r1=344722&r2=344723&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Oct 17 20:14:37 2018
@@ -165,6 +165,9 @@ namespace {
     /// 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 @@ namespace {
     bool runOnMachineFunction(MachineFunction &MF) override {
       // Reset the subtarget each time through.
       Subtarget = &MF.getSubtarget<X86Subtarget>();
+      IndirectTlsSegRefs = MF.getFunction().hasFnAttribute(
+                             "indirect-tls-seg-refs");
       SelectionDAGISel::runOnMachineFunction(MF);
       return true;
     }
@@ -981,6 +986,7 @@ bool X86DAGToDAGISel::matchLoadInAddress
   // For more information see http://people.redhat.com/drepper/tls.pdf
   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Address))
     if (C->getSExtValue() == 0 && AM.Segment.getNode() == nullptr &&
+        !IndirectTlsSegRefs &&
         (Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
          Subtarget->isTargetFuchsia()))
       switch (N->getPointerInfo().getAddrSpace()) {

Modified: llvm/trunk/test/CodeGen/X86/tls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/tls.ll?rev=344723&r1=344722&r2=344723&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/tls.ll (original)
+++ llvm/trunk/test/CodeGen/X86/tls.ll Wed Oct 17 20:14:37 2018
@@ -1,5 +1,7 @@
 ; RUN: llc < %s -mtriple=i386-linux-gnu | FileCheck -check-prefix=X86_LINUX %s
 ; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64_LINUX %s
+; RUN: llc < %s -mtriple=i386-linux-gnu -fast-isel | FileCheck -check-prefix=X86_ISEL_LINUX %s
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel | FileCheck -check-prefix=X64_ISEL_LINUX %s
 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck -check-prefix=X86_WIN %s
 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck -check-prefix=X64_WIN %s
 ; RUN: llc < %s -mtriple=i686-pc-windows-gnu | FileCheck -check-prefix=MINGW32 %s
@@ -453,3 +455,59 @@ define i32* @f16() {
 
   ret i32* @i6
 }
+
+; NOTE: Similar to f1() but with direct TLS segment access disabled
+define i32 @f17() #0 {
+; X86_LINUX-LABEL: f17:
+; X86_LINUX:      movl %gs:0, %eax
+; X86_LINUX-NEXT: movl i1 at NTPOFF(%eax), %eax
+; X86_LINUX-NEXT: ret
+; X64_LINUX-LABEL: f17:
+; X64_LINUX:      movq %fs:0, %rax
+; X64_LINUX-NEXT: movl i1 at TPOFF(%rax), %eax
+; X64_LINUX-NEXT: ret
+; X86_ISEL_LINUX-LABEL: f17:
+; X86_ISEL_LINUX:      movl %gs:0, %eax
+; X86_ISEL_LINUX-NEXT: movl i1 at NTPOFF(%eax), %eax
+; X86_ISEL_LINUX-NEXT: ret
+; X64_ISEL_LINUX-LABEL: f17:
+; X64_ISEL_LINUX:      movq %fs:0, %rax
+; X64_ISEL_LINUX-NEXT: movl i1 at TPOFF(%rax), %eax
+; X64_ISEL_LINUX-NEXT: ret
+
+entry:
+	%tmp1 = load i32, i32* @i1
+	ret i32 %tmp1
+}
+
+; NOTE: Similar to f3() but with direct TLS segment access disabled
+define i32 @f18() #1 {
+; X86_LINUX-LABEL: f18:
+; X86_LINUX:      movl i2 at INDNTPOFF, %eax
+; X86_LINUX-NEXT: movl %gs:0, %ecx
+; X86_LINUX-NEXT: movl (%ecx,%eax), %eax
+; X86_LINUX-NEXT: ret
+; X64_LINUX-LABEL: f18:
+; X64_LINUX:      movq i2 at GOTTPOFF(%rip), %rax
+; X64_LINUX-NEXT: movq %fs:0, %rcx
+; X64_LINUX-NEXT: movl (%rcx,%rax), %eax
+; X64_LINUX-NEXT: ret
+; X86_ISEL_LINUX-LABEL: f18:
+; X86_ISEL_LINUX:      movl i2 at INDNTPOFF, %eax
+; X86_ISEL_LINUX-NEXT: movl %gs:0, %ecx
+; X86_ISEL_LINUX-NEXT: movl (%ecx,%eax), %eax
+; X86_ISEL_LINUX-NEXT: ret
+; X64_ISEL_LINUX-LABEL: f18:
+; X64_ISEL_LINUX:      movq i2 at GOTTPOFF(%rip), %rax
+; X64_ISEL_LINUX-NEXT: movq %fs:0, %rcx
+; X64_ISEL_LINUX-NEXT: movl (%rcx,%rax), %eax
+; X64_ISEL_LINUX-NEXT: ret
+
+
+entry:
+	%tmp1 = load i32, i32* @i2
+	ret i32 %tmp1
+}
+
+attributes #0 = { "indirect-tls-seg-refs" }
+attributes #1 = { nounwind "indirect-tls-seg-refs" }




More information about the llvm-commits mailing list