Skip to content

Commit 228978c

Browse files
committed
[X86ISelLowering] Fix TLSADDR lowering when shrink-wrapping is enabled.
TLSADDR nodes are lowered into actuall calls inside MC. In order to prevent shrink-wrapping from pushing prologue/epilogue past them (which result in TLS variables being accessed before the stack frame is set up), we put markers, so that the stack gets adjusted properly. Thanks to Quentin Colombet for guidance/help on how to fix this problem! llvm-svn: 261387
1 parent 467b5b9 commit 228978c

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22657,6 +22657,35 @@ X86TargetLowering::EmitLoweredCatchPad(MachineInstr *MI,
2265722657
return BB;
2265822658
}
2265922659

22660+
MachineBasicBlock *
22661+
X86TargetLowering::EmitLoweredTLSAddr(MachineInstr *MI,
22662+
MachineBasicBlock *BB) const {
22663+
// So, here we replace TLSADDR with the sequence:
22664+
// adjust_stackdown -> TLSADDR -> adjust_stackup.
22665+
// We need this because TLSADDR is lowered into calls
22666+
// inside MC, therefore without the two markers shrink-wrapping
22667+
// may push the prologue/epilogue pass them.
22668+
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
22669+
DebugLoc DL = MI->getDebugLoc();
22670+
MachineFunction &MF = *BB->getParent();
22671+
22672+
// Emit CALLSEQ_START right before the instruction.
22673+
unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
22674+
MachineInstrBuilder CallseqStart =
22675+
BuildMI(MF, DL, TII.get(AdjStackDown)).addImm(0);
22676+
BB->insert(MachineBasicBlock::iterator(MI), CallseqStart);
22677+
22678+
// Emit CALLSEQ_END right after the instruction.
22679+
// We don't call erase from parent because we want to keep the
22680+
// original instruction around.
22681+
unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
22682+
MachineInstrBuilder CallseqEnd =
22683+
BuildMI(MF, DL, TII.get(AdjStackUp)).addImm(0).addImm(0);
22684+
BB->insertAfter(MachineBasicBlock::iterator(MI), CallseqEnd);
22685+
22686+
return BB;
22687+
}
22688+
2266022689
MachineBasicBlock *
2266122690
X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
2266222691
MachineBasicBlock *BB) const {
@@ -23037,6 +23066,11 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
2303723066
case X86::TCRETURNri64:
2303823067
case X86::TCRETURNmi64:
2303923068
return BB;
23069+
case X86::TLS_addr32:
23070+
case X86::TLS_addr64:
23071+
case X86::TLS_base_addr32:
23072+
case X86::TLS_base_addr64:
23073+
return EmitLoweredTLSAddr(MI, BB);
2304023074
case X86::WIN_ALLOCA:
2304123075
return EmitLoweredWinAlloca(MI, BB);
2304223076
case X86::CATCHRET:

llvm/lib/Target/X86/X86ISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,9 @@ namespace llvm {
11381138
MachineBasicBlock *EmitLoweredSegAlloca(MachineInstr *MI,
11391139
MachineBasicBlock *BB) const;
11401140

1141+
MachineBasicBlock *EmitLoweredTLSAddr(MachineInstr *MI,
1142+
MachineBasicBlock *BB) const;
1143+
11411144
MachineBasicBlock *EmitLoweredTLSCall(MachineInstr *MI,
11421145
MachineBasicBlock *BB) const;
11431146

llvm/lib/Target/X86/X86InstrCompiler.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7,
436436
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
437437
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
438438
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
439-
Uses = [ESP] in {
439+
usesCustomInserter = 1, Uses = [ESP] in {
440440
def TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym),
441441
"# TLS_addr32",
442442
[(X86tlsaddr tls32addr:$sym)]>,
@@ -456,7 +456,7 @@ let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
456456
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
457457
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
458458
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
459-
Uses = [RSP] in {
459+
usesCustomInserter = 1, Uses = [RSP] in {
460460
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
461461
"# TLS_addr64",
462462
[(X86tlsaddr tls64addr:$sym)]>,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
; Testcase generated from the following code:
2+
; extern __thread int i;
3+
; void f();
4+
; int g(void) {
5+
; if (i) {
6+
; i = 0;
7+
; f();
8+
; }
9+
; return i;
10+
; }
11+
; We want to make sure that TLS variables are not accessed before
12+
; the stack frame is set up.
13+
14+
; RUN: llc < %s -relocation-model=pic | FileCheck %s
15+
16+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
17+
target triple = "x86_64-unknown-freebsd11.0"
18+
19+
@i = external thread_local global i32, align 4
20+
21+
define i32 @g() #0 {
22+
entry:
23+
%tmp = load i32, i32* @i, align 4
24+
%tobool = icmp eq i32 %tmp, 0
25+
br i1 %tobool, label %if.end, label %if.then
26+
27+
if.then: ; preds = %entry
28+
store i32 0, i32* @i, align 4
29+
tail call void (...) @f() #2
30+
%.pre = load i32, i32* @i, align 4
31+
br label %if.end
32+
33+
if.end: ; preds = %if.then, %entry
34+
%tmp1 = phi i32 [ 0, %entry ], [ %.pre, %if.then ]
35+
ret i32 %tmp1
36+
}
37+
38+
; CHECK: g: # @g
39+
; CHECK-NEXT: .cfi_startproc
40+
; CHECK-NEXT: # BB#0: # %entry
41+
; CHECK-NEXT: pushq %rbp
42+
; CHECK-NEXT: .Ltmp0:
43+
; CHECK-NEXT: .cfi_def_cfa_offset 16
44+
; CHECK-NEXT: .Ltmp1:
45+
; CHECK-NEXT: .cfi_offset %rbp, -16
46+
; CHECK-NEXT: movq %rsp, %rbp
47+
; CHECK-NEXT: .Ltmp2:
48+
; CHECK-NEXT: .cfi_def_cfa_register %rbp
49+
; CHECK-NEXT: pushq %rbx
50+
; CHECK-NEXT: pushq %rax
51+
; CHECK-NEXT: .Ltmp3:
52+
; CHECK-NEXT: .cfi_offset %rbx, -24
53+
; CHECK-NEXT: data16
54+
; CHECK-NEXT: leaq i@TLSGD(%rip), %rdi
55+
56+
declare void @f(...) #1
57+
58+
attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
59+
attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
60+
attributes #2 = { nounwind }

0 commit comments

Comments
 (0)