Skip to content

Commit ea6bb26

Browse files
nagisaYangKeao
andauthored
[X86] add dwarf annotation for inline stack probe (#100)
While probing stack, the stack register is moved without dwarf information, which could cause panic if unwind the backtrace. This commit only add annotation for the inline stack probe case. Dwarf information for the loop case should be done in another patch and need further discussion. Reviewed By: nagisa Differential Revision: https://reviews.llvm.org/D99579 Co-authored-by: YangKeao <[email protected]>
1 parent a7f0c22 commit ea6bb26

6 files changed

+81
-35
lines changed

llvm/lib/Target/X86/X86FrameLowering.cpp

+23-3
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ void X86FrameLowering::emitStackProbeInlineGenericBlock(
553553
MachineBasicBlock::iterator MBBI, const DebugLoc &DL, uint64_t Offset,
554554
uint64_t AlignOffset) const {
555555

556+
const bool NeedsDwarfCFI = needsDwarfCFI(MF);
557+
const bool HasFP = hasFP(MF);
556558
const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>();
557559
const X86TargetLowering &TLI = *STI.getTargetLowering();
558560
const unsigned Opc = getSUBriOpcode(Uses64BitFramePtr, Offset);
@@ -570,6 +572,11 @@ void X86FrameLowering::emitStackProbeInlineGenericBlock(
570572
.addReg(StackPtr)
571573
.addImm(StackProbeSize - AlignOffset)
572574
.setMIFlag(MachineInstr::FrameSetup);
575+
if (!HasFP && NeedsDwarfCFI) {
576+
BuildCFI(MBB, MBBI, DL,
577+
MCCFIInstruction::createAdjustCfaOffset(
578+
nullptr, StackProbeSize - AlignOffset));
579+
}
573580
MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
574581

575582
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(MovMIOpc))
@@ -591,7 +598,11 @@ void X86FrameLowering::emitStackProbeInlineGenericBlock(
591598
.setMIFlag(MachineInstr::FrameSetup);
592599
MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
593600

594-
601+
if (!HasFP && NeedsDwarfCFI) {
602+
BuildCFI(
603+
MBB, MBBI, DL,
604+
MCCFIInstruction::createAdjustCfaOffset(nullptr, StackProbeSize));
605+
}
595606
addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(MovMIOpc))
596607
.setMIFlag(MachineInstr::FrameSetup),
597608
StackPtr, false, 0)
@@ -607,6 +618,8 @@ void X86FrameLowering::emitStackProbeInlineGenericBlock(
607618
.addReg(StackPtr)
608619
.addImm(ChunkSize)
609620
.setMIFlag(MachineInstr::FrameSetup);
621+
// No need to adjust Dwarf CFA offset here, the last position of the stack has
622+
// been defined
610623
MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
611624
}
612625

@@ -1200,6 +1213,13 @@ bool X86FrameLowering::has128ByteRedZone(const MachineFunction& MF) const {
12001213
return Is64Bit && !IsWin64CC && !Fn.hasFnAttribute(Attribute::NoRedZone);
12011214
}
12021215

1216+
bool X86FrameLowering::isWin64Prologue(const MachineFunction &MF) const {
1217+
return MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
1218+
}
1219+
1220+
bool X86FrameLowering::needsDwarfCFI(const MachineFunction &MF) const {
1221+
return !isWin64Prologue(MF) && MF.needsFrameMoves();
1222+
}
12031223

12041224
/// emitPrologue - Push callee-saved registers onto the stack, which
12051225
/// automatically adjust the stack pointer. Adjust the stack pointer to allocate
@@ -1305,13 +1325,13 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
13051325
MF.hasEHFunclets() && Personality == EHPersonality::CoreCLR;
13061326
bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
13071327
bool HasFP = hasFP(MF);
1308-
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
1328+
bool IsWin64Prologue = isWin64Prologue(MF);
13091329
bool NeedsWin64CFI = IsWin64Prologue && Fn.needsUnwindTableEntry();
13101330
// FIXME: Emit FPO data for EH funclets.
13111331
bool NeedsWinFPO =
13121332
!IsFunclet && STI.isTargetWin32() && MMI.getModule()->getCodeViewFlag();
13131333
bool NeedsWinCFI = NeedsWin64CFI || NeedsWinFPO;
1314-
bool NeedsDwarfCFI = !IsWin64Prologue && MF.needsFrameMoves();
1334+
bool NeedsDwarfCFI = needsDwarfCFI(MF);
13151335
Register FramePtr = TRI->getFrameRegister(MF);
13161336
const Register MachineFramePtr =
13171337
STI.isTarget64BitILP32()

llvm/lib/Target/X86/X86FrameLowering.h

+4
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ class X86FrameLowering : public TargetFrameLowering {
192192
bool has128ByteRedZone(const MachineFunction& MF) const;
193193

194194
private:
195+
bool isWin64Prologue(const MachineFunction &MF) const;
196+
197+
bool needsDwarfCFI(const MachineFunction &MF) const;
198+
195199
uint64_t calculateMaxStackAlign(const MachineFunction &MF) const;
196200

197201
/// Emit target stack probe as a call to a helper function

llvm/test/CodeGen/X86/stack-clash-medium-natural-probes-mutliple-objects.ll

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ define i32 @foo() local_unnamed_addr #0 {
88
; CHECK-LABEL: foo:
99
; CHECK: # %bb.0:
1010
; CHECK-NEXT: subq $4096, %rsp # imm = 0x1000
11+
; CHECK-NEXT: .cfi_adjust_cfa_offset 4096
1112
; CHECK-NEXT: movq $0, (%rsp)
1213
; CHECK-NEXT: subq $1784, %rsp # imm = 0x6F8
1314
; CHECK-NEXT: .cfi_def_cfa_offset 5888

llvm/test/CodeGen/X86/stack-clash-medium-natural-probes.ll

+12-14
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,18 @@ target triple = "x86_64-unknown-linux-gnu"
77
define i32 @foo() local_unnamed_addr #0 {
88

99
; CHECK-LABEL: foo:
10-
; CHECK: # %bb.0:
11-
; CHECK-NEXT: subq $4096, %rsp # imm = 0x1000
12-
; CHECK-NEXT: movq $0, (%rsp)
13-
; CHECK-NEXT: subq $3784, %rsp # imm = 0xEC8
14-
; CHECK-NEXT: .cfi_def_cfa_offset 7888
15-
; CHECK-NEXT: movl $1, 264(%rsp)
16-
; CHECK-NEXT: movl $1, 4664(%rsp)
17-
; CHECK-NEXT: movl -128(%rsp), %eax
18-
; CHECK-NEXT: addq $7880, %rsp # imm = 0x1EC8
19-
; CHECK-NEXT: .cfi_def_cfa_offset 8
20-
; CHECK-NEXT: retq
21-
22-
23-
10+
; CHECK: # %bb.0:
11+
; CHECK-NEXT: subq $4096, %rsp # imm = 0x1000
12+
; CHECK-NEXT: .cfi_adjust_cfa_offset 4096
13+
; CHECK-NEXT: movq $0, (%rsp)
14+
; CHECK-NEXT: subq $3784, %rsp # imm = 0xEC8
15+
; CHECK-NEXT: .cfi_def_cfa_offset 7888
16+
; CHECK-NEXT: movl $1, 264(%rsp)
17+
; CHECK-NEXT: movl $1, 4664(%rsp)
18+
; CHECK-NEXT: movl -128(%rsp), %eax
19+
; CHECK-NEXT: addq $7880, %rsp # imm = 0x1EC8
20+
; CHECK-NEXT: .cfi_def_cfa_offset 8
21+
; CHECK-NEXT: retq
2422
%a = alloca i32, i64 2000, align 16
2523
%b0 = getelementptr inbounds i32, i32* %a, i64 98
2624
%b1 = getelementptr inbounds i32, i32* %a, i64 1198

llvm/test/CodeGen/X86/stack-clash-medium.ll

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
1-
; RUN: llc -mtriple=x86_64-linux-android < %s | FileCheck -check-prefix=CHECK-X86-64 %s
2-
; RUN: llc -mtriple=i686-linux-android < %s | FileCheck -check-prefix=CHECK-X86-32 %s
1+
; RUN: llc -mtriple=x86_64-linux-android < %s | FileCheck -check-prefix=CHECK-X86-64 %s
2+
; RUN: llc -mtriple=i686-linux-android < %s | FileCheck -check-prefix=CHECK-X86-32 %s
33

44
define i32 @foo() local_unnamed_addr #0 {
5+
; CHECK-X86-64-LABEL: foo:
6+
; CHECK-X86-64: # %bb.0:
7+
; CHECK-X86-64-NEXT: subq $4096, %rsp # imm = 0x1000
8+
; CHECK-X86-64-NEXT: .cfi_adjust_cfa_offset 4096
9+
; CHECK-X86-64-NEXT: movq $0, (%rsp)
10+
; CHECK-X86-64-NEXT: subq $3784, %rsp # imm = 0xEC8
11+
; CHECK-X86-64-NEXT: .cfi_def_cfa_offset 7888
12+
; CHECK-X86-64-NEXT: movl $1, 672(%rsp)
13+
; CHECK-X86-64-NEXT: movl -128(%rsp), %eax
14+
; CHECK-X86-64-NEXT: addq $7880, %rsp # imm = 0x1EC8
15+
; CHECK-X86-64-NEXT: .cfi_def_cfa_offset 8
16+
; CHECK-X86-64-NEXT: retq
17+
;
18+
; CHECK-X86-32-LABEL: foo:
19+
; CHECK-X86-32: # %bb.0:
20+
; CHECK-X86-32-NEXT: subl $4096, %esp # imm = 0x1000
21+
; CHECK-X86-32-NEXT: .cfi_adjust_cfa_offset 4096
22+
; CHECK-X86-32-NEXT: movl $0, (%esp)
23+
; CHECK-X86-32-NEXT: subl $3916, %esp # imm = 0xF4C
24+
; CHECK-X86-32-NEXT: .cfi_def_cfa_offset 8016
25+
; CHECK-X86-32-NEXT: movl $1, 800(%esp)
26+
; CHECK-X86-32-NEXT: movl (%esp), %eax
27+
; CHECK-X86-32-NEXT: addl $8012, %esp # imm = 0x1F4C
28+
; CHECK-X86-32-NEXT: .cfi_def_cfa_offset 4
29+
; CHECK-X86-32-NEXT: retl
530
%a = alloca i32, i64 2000, align 16
631
%b = getelementptr inbounds i32, i32* %a, i64 200
732
store volatile i32 1, i32* %b

llvm/test/CodeGen/X86/stack-clash-unknown-call.ll

+14-16
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@ target triple = "x86_64-unknown-linux-gnu"
77
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg);
88

99
define void @foo() local_unnamed_addr #0 {
10-
11-
;CHECK-LABEL: foo:
12-
;CHECK: # %bb.0:
13-
;CHECK-NEXT: subq $4096, %rsp # imm = 0x1000
14-
; it's important that we don't use the call as a probe here
15-
;CHECK-NEXT: movq $0, (%rsp)
16-
;CHECK-NEXT: subq $3912, %rsp # imm = 0xF48
17-
;CHECK-NEXT: .cfi_def_cfa_offset 8016
18-
;CHECK-NEXT: movq %rsp, %rdi
19-
;CHECK-NEXT: movl $8000, %edx # imm = 0x1F40
20-
;CHECK-NEXT: xorl %esi, %esi
21-
;CHECK-NEXT: callq memset
22-
;CHECK-NEXT: addq $8008, %rsp # imm = 0x1F48
23-
;CHECK-NEXT: .cfi_def_cfa_offset 8
24-
;CHECK-NEXT: retq
25-
10+
; CHECK-LABEL: foo:
11+
; CHECK: # %bb.0:
12+
; CHECK-NEXT: subq $4096, %rsp # imm = 0x1000
13+
; CHECK-NEXT: .cfi_adjust_cfa_offset 4096
14+
; CHECK-NEXT: movq $0, (%rsp)
15+
; CHECK-NEXT: subq $3912, %rsp # imm = 0xF48
16+
; CHECK-NEXT: .cfi_def_cfa_offset 8016
17+
; CHECK-NEXT: movq %rsp, %rdi
18+
; CHECK-NEXT: movl $8000, %edx # imm = 0x1F40
19+
; CHECK-NEXT: xorl %esi, %esi
20+
; CHECK-NEXT: callq memset@PLT
21+
; CHECK-NEXT: addq $8008, %rsp # imm = 0x1F48
22+
; CHECK-NEXT: .cfi_def_cfa_offset 8
23+
; CHECK-NEXT: retq
2624
%a = alloca i8, i64 8000, align 16
2725
call void @llvm.memset.p0i8.i64(i8* align 16 %a, i8 0, i64 8000, i1 false)
2826
ret void

0 commit comments

Comments
 (0)