diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -72,6 +72,27 @@ } // 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 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 @@ } } -/// 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 --- /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 + +@gd = external thread_local global i32 +@ld = internal thread_local global i32 0 + +define i32 @tls_get_addr() { +; CHECK-LABEL: tls_get_addr: +; CHECK: #noautopadding +; 32: leal gd@TLSGD(,%ebx), %eax +; 32: calll ___tls_get_addr@PLT +; 64: data16 +; 64: leaq gd@TLSGD(%rip), %rdi +; 64: callq __tls_get_addr@PLT +; CHECK: #autopadding +; CHECK: #noautopadding +; 32: leal ld@TLSLDM(%ebx), %eax +; 32: calll ___tls_get_addr@PLT +; 64: leaq ld@TLSLD(%rip), %rdi +; 64: callq __tls_get_addr@PLT +; CHECK: #autopadding + %1 = load i32, i32* @gd + %2 = load i32, i32* @ld + %3 = add i32 %1, %2 + ret i32 %3 +}