forked from OSchip/llvm-project
[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
This commit is contained in:
parent
9583a3f262
commit
0cb415c189
|
@ -72,6 +72,27 @@ private:
|
|||
|
||||
} // 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");
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue