[llvm] 0cb415c - [X86][BranchAlign] Suppress branch alignment for {, _}__tls_get_addr

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 18 18:15:48 PST 2020


Author: Fangrui Song
Date: 2020-01-18T18:14:51-08:00
New Revision: 0cb415c189092e75eaaccabbae41497e446fb3f1

URL: https://github.com/llvm/llvm-project/commit/0cb415c189092e75eaaccabbae41497e446fb3f1
DIFF: https://github.com/llvm/llvm-project/commit/0cb415c189092e75eaaccabbae41497e446fb3f1.diff

LOG: [X86][BranchAlign] Suppress branch alignment for {,_}__tls_get_addr

The x86-64 General Dynamic TLS code sequence uses prefixes to allow
linker relaxation.  Adding segment override prefix or NOPs can break
linker relaxation (ld -pie/-no-pie).

i386 General Dynamic and x86-64 Local Dynamic do not use prefixes, but
for simplicity, just disable auto padding consistently.

Reviewed By: skan, LuoYuanke

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

Added: 
    llvm/test/CodeGen/X86/align-branch-boundary-suppressions-tls.ll

Modified: 
    llvm/lib/Target/X86/X86MCInstLower.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index 2fc9a2af01d7..44576a07d642 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -72,6 +72,27 @@ class X86MCInstLower {
 
 } // end anonymous namespace
 
+/// A RAII helper which defines a region of instructions which can't have
+/// padding added between them for correctness.
+struct NoAutoPaddingScope {
+  MCStreamer &OS;
+  const bool OldAllowAutoPadding;
+  NoAutoPaddingScope(MCStreamer &OS)
+      : OS(OS), OldAllowAutoPadding(OS.getAllowAutoPadding()) {
+    changeAndComment(false);
+  }
+  ~NoAutoPaddingScope() { changeAndComment(OldAllowAutoPadding); }
+  void changeAndComment(bool b) {
+    if (b == OS.getAllowAutoPadding())
+      return;
+    OS.setAllowAutoPadding(b);
+    if (b)
+      OS.emitRawComment("autopadding");
+    else
+      OS.emitRawComment("noautopadding");
+  }
+};
+
 // Emit a minimal sequence of nops spanning NumBytes bytes.
 static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit,
                      const MCSubtargetInfo &STI);
@@ -929,6 +950,7 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
 
 void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering,
                                  const MachineInstr &MI) {
+  NoAutoPaddingScope NoPadScope(*OutStreamer);
   bool Is64Bits = MI.getOpcode() == X86::TLS_addr64 ||
                   MI.getOpcode() == X86::TLS_base_addr64;
   MCContext &Ctx = OutStreamer->getContext();
@@ -1161,29 +1183,6 @@ static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit,
   }
 }
 
-/// A RAII helper which defines a region of instructions which can't have
-/// padding added between them for correctness.
-struct NoAutoPaddingScope {
-  MCStreamer &OS;
-  const bool OldAllowAutoPadding;
-  NoAutoPaddingScope(MCStreamer &OS)
-    : OS(OS), OldAllowAutoPadding(OS.getAllowAutoPadding()) {
-    changeAndComment(false);
-  }
-  ~NoAutoPaddingScope() {
-    changeAndComment(OldAllowAutoPadding);
-  }
-  void changeAndComment(bool b) {
-    if (b == OS.getAllowAutoPadding())
-      return;
-    OS.setAllowAutoPadding(b);
-    if (b)
-      OS.emitRawComment("autopadding");
-    else
-      OS.emitRawComment("noautopadding");
-  }
-};
-
 void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
                                     X86MCInstLower &MCIL) {
   assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");

diff  --git a/llvm/test/CodeGen/X86/align-branch-boundary-suppressions-tls.ll b/llvm/test/CodeGen/X86/align-branch-boundary-suppressions-tls.ll
new file mode 100644
index 000000000000..d980e60e5fc5
--- /dev/null
+++ b/llvm/test/CodeGen/X86/align-branch-boundary-suppressions-tls.ll
@@ -0,0 +1,30 @@
+;; Test that we don't pad the x86-64 General Dynamic/Local Dynamic TLS code
+;; sequence. It uses prefixes to allow linker relaxation. We need to disable
+;; prefix or nop padding for it. For simplicity and consistency, disable for
+;; Local Dynamic and 32-bit as well.
+; RUN: llc -mtriple=i386 -relocation-model=pic -x86-branches-within-32B-boundaries < %s | FileCheck --check-prefixes=CHECK,32 %s
+; RUN: llc -mtriple=x86_64 -relocation-model=pic -x86-branches-within-32B-boundaries < %s | FileCheck --check-prefixes=CHECK,64 %s
+
+ at gd = external thread_local global i32
+ at ld = internal thread_local global i32 0
+
+define i32 @tls_get_addr() {
+; CHECK-LABEL: tls_get_addr:
+; CHECK: #noautopadding
+; 32: leal gd at TLSGD(,%ebx), %eax
+; 32: calll ___tls_get_addr at PLT
+; 64: data16
+; 64: leaq gd at TLSGD(%rip), %rdi
+; 64: callq __tls_get_addr at PLT
+; CHECK: #autopadding
+; CHECK: #noautopadding
+; 32: leal ld at TLSLDM(%ebx), %eax
+; 32: calll ___tls_get_addr at PLT
+; 64: leaq ld at TLSLD(%rip), %rdi
+; 64: callq __tls_get_addr at PLT
+; CHECK: #autopadding
+  %1 = load i32, i32* @gd
+  %2 = load i32, i32* @ld
+  %3 = add i32 %1, %2
+  ret i32 %3
+}


        


More information about the llvm-commits mailing list