Skip to content

Commit d0ea42a

Browse files
[AArch64] Async unwind - function epilogues
Reviewed By: MaskRay, chill Differential Revision: https://reviews.llvm.org/D112330
1 parent 7738db2 commit d0ea42a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1914
-296
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 132 additions & 61 deletions
Large diffs are not rendered by default.

llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ class AArch64FrameLowering : public TargetFrameLowering {
149149
MachineBasicBlock::iterator MBBI) const;
150150
void emitCalleeSavedSVELocations(MachineBasicBlock &MBB,
151151
MachineBasicBlock::iterator MBBI) const;
152+
void emitCalleeSavedGPRRestores(MachineBasicBlock &MBB,
153+
MachineBasicBlock::iterator MBBI) const;
154+
void emitCalleeSavedSVERestores(MachineBasicBlock &MBB,
155+
MachineBasicBlock::iterator MBBI) const;
152156
};
153157

154158
} // End llvm namespace

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4147,11 +4147,12 @@ static MCCFIInstruction createDefCFAExpression(const TargetRegisterInfo &TRI,
41474147

41484148
MCCFIInstruction llvm::createDefCFA(const TargetRegisterInfo &TRI,
41494149
unsigned FrameReg, unsigned Reg,
4150-
const StackOffset &Offset) {
4150+
const StackOffset &Offset,
4151+
bool LastAdjustmentWasScalable) {
41514152
if (Offset.getScalable())
41524153
return createDefCFAExpression(TRI, Reg, Offset);
41534154

4154-
if (FrameReg == Reg)
4155+
if (FrameReg == Reg && !LastAdjustmentWasScalable)
41554156
return MCCFIInstruction::cfiDefCfaOffset(nullptr, int(Offset.getFixed()));
41564157

41574158
unsigned DwarfReg = TRI.getDwarfRegNum(Reg, true);
@@ -4283,8 +4284,8 @@ static void emitFrameOffsetAdj(MachineBasicBlock &MBB,
42834284
const TargetSubtargetInfo &STI = MF.getSubtarget();
42844285
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
42854286

4286-
unsigned CFIIndex =
4287-
MF.addFrameInst(createDefCFA(TRI, FrameReg, DestReg, CFAOffset));
4287+
unsigned CFIIndex = MF.addFrameInst(
4288+
createDefCFA(TRI, FrameReg, DestReg, CFAOffset, VScale != 1));
42884289
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
42894290
.addCFIIndex(CFIIndex)
42904291
.setMIFlags(Flag);

llvm/lib/Target/AArch64/AArch64InstrInfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ bool isNZCVTouchedInInstructionRange(const MachineInstr &DefMI,
396396
const TargetRegisterInfo *TRI);
397397

398398
MCCFIInstruction createDefCFA(const TargetRegisterInfo &TRI, unsigned FrameReg,
399-
unsigned Reg, const StackOffset &Offset);
399+
unsigned Reg, const StackOffset &Offset,
400+
bool LastAdjustmentWasScalable = true);
400401
MCCFIInstruction createCFAOffset(const TargetRegisterInfo &MRI, unsigned Reg,
401402
const StackOffset &OffsetFromDefCFA);
402403

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515

1616
#include "AArch64MachineFunctionInfo.h"
1717
#include "AArch64InstrInfo.h"
18-
#include "llvm/MC/MCAsmInfo.h"
18+
#include "AArch64Subtarget.h"
1919
#include "llvm/IR/Constants.h"
2020
#include "llvm/IR/Metadata.h"
2121
#include "llvm/IR/Module.h"
22+
#include "llvm/MC/MCAsmInfo.h"
2223

2324
using namespace llvm;
2425

@@ -118,17 +119,22 @@ bool AArch64FunctionInfo::shouldSignReturnAddress() const {
118119
}
119120

120121
bool AArch64FunctionInfo::needsDwarfUnwindInfo() const {
121-
if (!NeedsDwarfUnwindInfo.hasValue())
122+
if (!NeedsDwarfUnwindInfo)
122123
NeedsDwarfUnwindInfo = MF.needsFrameMoves() &&
123124
!MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
124125

125-
return NeedsDwarfUnwindInfo.getValue();
126+
return *NeedsDwarfUnwindInfo;
126127
}
127128

128129
bool AArch64FunctionInfo::needsAsyncDwarfUnwindInfo() const {
129-
if (!NeedsDwarfAsyncUnwindInfo.hasValue())
130-
NeedsDwarfAsyncUnwindInfo =
131-
needsDwarfUnwindInfo() &&
132-
MF.getFunction().getUWTableKind() == UWTableKind::Async;
133-
return NeedsDwarfAsyncUnwindInfo.getValue();
130+
if (!NeedsAsyncDwarfUnwindInfo) {
131+
const Function &F = MF.getFunction();
132+
// The check got "minsize" is because epilogue unwind info is not emitted
133+
// (yet) for homogeneous epilogues, outlined functions, and functions
134+
// outlined from.
135+
NeedsAsyncDwarfUnwindInfo = needsDwarfUnwindInfo() &&
136+
F.getUWTableKind() == UWTableKind::Async &&
137+
!F.hasMinSize();
138+
}
139+
return *NeedsAsyncDwarfUnwindInfo;
134140
}

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
178178
mutable Optional<bool> NeedsDwarfUnwindInfo;
179179

180180
/// True if the function need asynchronous unwind information.
181-
mutable Optional<bool> NeedsDwarfAsyncUnwindInfo;
181+
mutable Optional<bool> NeedsAsyncDwarfUnwindInfo;
182182

183183
public:
184184
explicit AArch64FunctionInfo(MachineFunction &MF);

llvm/test/CodeGen/AArch64/GlobalISel/byval-call.ll

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
declare void @byval_i32(i32* byval(i32) %ptr)
55

6-
define void @call_byval_i32(i32* %incoming) {
6+
define void @call_byval_i32(i32* %incoming) uwtable {
77
; CHECK-LABEL: call_byval_i32:
88
; CHECK: // %bb.0:
99
; CHECK-NEXT: sub sp, sp, #32
@@ -15,14 +15,16 @@ define void @call_byval_i32(i32* %incoming) {
1515
; CHECK-NEXT: bl byval_i32
1616
; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
1717
; CHECK-NEXT: add sp, sp, #32
18+
; CHECK-NEXT: .cfi_def_cfa_offset 0
19+
; CHECK-NEXT: .cfi_restore w30
1820
; CHECK-NEXT: ret
1921
call void @byval_i32(i32* byval(i32) %incoming)
2022
ret void
2123
}
2224

2325
declare void @byval_a64i32([64 x i32]* byval([64 x i32]) %ptr)
2426

25-
define void @call_byval_a64i32([64 x i32]* %incoming) {
27+
define void @call_byval_a64i32([64 x i32]* %incoming) uwtable {
2628
; CHECK-LABEL: call_byval_a64i32:
2729
; CHECK: // %bb.0:
2830
; CHECK-NEXT: sub sp, sp, #288
@@ -67,9 +69,14 @@ define void @call_byval_a64i32([64 x i32]* %incoming) {
6769
; CHECK-NEXT: ldr q0, [x0, #240]
6870
; CHECK-NEXT: str q0, [sp, #240]
6971
; CHECK-NEXT: bl byval_a64i32
72+
; CHECK-NEXT: .cfi_def_cfa wsp, 288
7073
; CHECK-NEXT: ldp x29, x30, [sp, #256] // 16-byte Folded Reload
7174
; CHECK-NEXT: ldr x28, [sp, #272] // 8-byte Folded Reload
7275
; CHECK-NEXT: add sp, sp, #288
76+
; CHECK-NEXT: .cfi_def_cfa_offset 0
77+
; CHECK-NEXT: .cfi_restore w28
78+
; CHECK-NEXT: .cfi_restore w30
79+
; CHECK-NEXT: .cfi_restore w29
7380
; CHECK-NEXT: ret
7481
call void @byval_a64i32([64 x i32]* byval([64 x i32]) %incoming)
7582
ret void

llvm/test/CodeGen/AArch64/arm64-fp128.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ define dso_local i32 @test_br_cc() uwtable {
282282
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
283283
; CHECK-NEXT: .cfi_def_cfa_offset 16
284284
; CHECK-NEXT: .cfi_offset w30, -16
285+
; CHECK-NEXT: .cfi_remember_state
285286
; CHECK-NEXT: adrp x8, lhs
286287
; CHECK-NEXT: ldr q0, [x8, :lo12:lhs]
287288
; CHECK-NEXT: adrp x8, rhs
@@ -292,10 +293,15 @@ define dso_local i32 @test_br_cc() uwtable {
292293
; CHECK-NEXT: // %bb.1: // %iftrue
293294
; CHECK-NEXT: mov w0, #42
294295
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
296+
; CHECK-NEXT: .cfi_def_cfa_offset 0
297+
; CHECK-NEXT: .cfi_restore w30
295298
; CHECK-NEXT: ret
296299
; CHECK-NEXT: .LBB11_2: // %iffalse
300+
; CHECK-NEXT: .cfi_restore_state
297301
; CHECK-NEXT: mov w0, #29
298302
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
303+
; CHECK-NEXT: .cfi_def_cfa_offset 0
304+
; CHECK-NEXT: .cfi_restore w30
299305
; CHECK-NEXT: ret
300306

301307
%lhs = load fp128, fp128* @lhs, align 16

llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,16 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind uwtable {
359359
; ENABLE-NEXT: b.ne LBB4_2
360360
; ENABLE-NEXT: ; %bb.3: ; %for.end
361361
; ENABLE-NEXT: lsl w0, w19, #3
362+
; ENABLE-NEXT: .cfi_def_cfa wsp, 32
362363
; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
363364
; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
365+
; ENABLE-NEXT: .cfi_def_cfa_offset 0
366+
; ENABLE-NEXT: .cfi_restore w30
367+
; ENABLE-NEXT: .cfi_restore w29
368+
; ENABLE-NEXT: .cfi_restore w19
369+
; ENABLE-NEXT: .cfi_restore w20
364370
; ENABLE-NEXT: ret
365371
; ENABLE-NEXT: LBB4_4: ; %if.else
366-
; ENABLE-NEXT: .cfi_def_cfa wsp, 0
367-
; ENABLE-NEXT: .cfi_same_value w30
368-
; ENABLE-NEXT: .cfi_same_value w29
369-
; ENABLE-NEXT: .cfi_same_value w19
370-
; ENABLE-NEXT: .cfi_same_value w20
371372
; ENABLE-NEXT: lsl w0, w1, #1
372373
; ENABLE-NEXT: ret
373374
;
@@ -399,8 +400,14 @@ define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind uwtable {
399400
; DISABLE-NEXT: LBB4_4: ; %if.else
400401
; DISABLE-NEXT: lsl w0, w1, #1
401402
; DISABLE-NEXT: LBB4_5: ; %if.end
403+
; DISABLE-NEXT: .cfi_def_cfa wsp, 32
402404
; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
403405
; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
406+
; DISABLE-NEXT: .cfi_def_cfa_offset 0
407+
; DISABLE-NEXT: .cfi_restore w30
408+
; DISABLE-NEXT: .cfi_restore w29
409+
; DISABLE-NEXT: .cfi_restore w19
410+
; DISABLE-NEXT: .cfi_restore w20
404411
; DISABLE-NEXT: ret
405412
entry:
406413
%tobool = icmp eq i32 %cond, 0
@@ -471,23 +478,23 @@ define i32 @variadicFunc(i32 %cond, i32 %count, ...) nounwind uwtable {
471478
; ENABLE-NEXT: b.ne LBB6_2
472479
; ENABLE-NEXT: LBB6_3: ; %for.end
473480
; ENABLE-NEXT: add sp, sp, #16
481+
; ENABLE-NEXT: .cfi_def_cfa_offset 0
474482
; ENABLE-NEXT: ret
475483
; ENABLE-NEXT: LBB6_4: ; %if.else
476-
; ENABLE-NEXT: .cfi_def_cfa wsp, 0
477484
; ENABLE-NEXT: lsl w0, w1, #1
478485
; ENABLE-NEXT: ret
479486
;
480487
; DISABLE-LABEL: variadicFunc:
481488
; DISABLE: ; %bb.0: ; %entry
482489
; DISABLE-NEXT: sub sp, sp, #16
483490
; DISABLE-NEXT: .cfi_def_cfa_offset 16
484-
; DISABLE-NEXT: cbz w0, LBB6_4
491+
; DISABLE-NEXT: cbz w0, LBB6_3
485492
; DISABLE-NEXT: ; %bb.1: ; %if.then
486493
; DISABLE-NEXT: add x8, sp, #16
487494
; DISABLE-NEXT: cmp w1, #1
488495
; DISABLE-NEXT: str x8, [sp, #8]
489496
; DISABLE-NEXT: mov w0, wzr
490-
; DISABLE-NEXT: b.lt LBB6_3
497+
; DISABLE-NEXT: b.lt LBB6_4
491498
; DISABLE-NEXT: LBB6_2: ; %for.body
492499
; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1
493500
; DISABLE-NEXT: ldr x8, [sp, #8]
@@ -497,12 +504,12 @@ define i32 @variadicFunc(i32 %cond, i32 %count, ...) nounwind uwtable {
497504
; DISABLE-NEXT: add w0, w0, w8
498505
; DISABLE-NEXT: subs w1, w1, #1
499506
; DISABLE-NEXT: b.ne LBB6_2
500-
; DISABLE-NEXT: LBB6_3: ; %if.end
501-
; DISABLE-NEXT: add sp, sp, #16
502-
; DISABLE-NEXT: ret
503-
; DISABLE-NEXT: LBB6_4: ; %if.else
507+
; DISABLE-NEXT: b LBB6_4
508+
; DISABLE-NEXT: LBB6_3: ; %if.else
504509
; DISABLE-NEXT: lsl w0, w1, #1
510+
; DISABLE-NEXT: LBB6_4: ; %if.end
505511
; DISABLE-NEXT: add sp, sp, #16
512+
; DISABLE-NEXT: .cfi_def_cfa_offset 0
506513
; DISABLE-NEXT: ret
507514
entry:
508515
%ap = alloca i8*, align 8
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=aarch64-linux %s -o - | FileCheck %s
3+
4+
define i32 @f0(i32 %x) #0 {
5+
; CHECK-LABEL: f0:
6+
; CHECK: // %bb.0: // %entry
7+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
8+
; CHECK-NEXT: .cfi_def_cfa_offset 16
9+
; CHECK-NEXT: .cfi_offset w30, -16
10+
; CHECK-NEXT: .cfi_remember_state
11+
; CHECK-NEXT: cbz w0, .LBB0_4
12+
; CHECK-NEXT: // %bb.1: // %entry
13+
; CHECK-NEXT: cmp w0, #2
14+
; CHECK-NEXT: b.eq .LBB0_5
15+
; CHECK-NEXT: // %bb.2: // %entry
16+
; CHECK-NEXT: cmp w0, #1
17+
; CHECK-NEXT: b.ne .LBB0_6
18+
; CHECK-NEXT: // %bb.3: // %if.then2
19+
; CHECK-NEXT: bl g1
20+
; CHECK-NEXT: add w0, w0, #1
21+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
22+
; CHECK-NEXT: .cfi_def_cfa_offset 0
23+
; CHECK-NEXT: .cfi_restore w30
24+
; CHECK-NEXT: ret
25+
; CHECK-NEXT: .LBB0_4:
26+
; CHECK-NEXT: .cfi_restore_state
27+
; CHECK-NEXT: .cfi_remember_state
28+
; CHECK-NEXT: mov w0, #1
29+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
30+
; CHECK-NEXT: .cfi_def_cfa_offset 0
31+
; CHECK-NEXT: .cfi_restore w30
32+
; CHECK-NEXT: ret
33+
; CHECK-NEXT: .LBB0_5: // %if.then5
34+
; CHECK-NEXT: .cfi_restore_state
35+
; CHECK-NEXT: .cfi_remember_state
36+
; CHECK-NEXT: bl g0
37+
; CHECK-NEXT: mov w8, #1
38+
; CHECK-NEXT: sub w0, w8, w0
39+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
40+
; CHECK-NEXT: .cfi_def_cfa_offset 0
41+
; CHECK-NEXT: .cfi_restore w30
42+
; CHECK-NEXT: ret
43+
; CHECK-NEXT: .LBB0_6: // %if.end7
44+
; CHECK-NEXT: .cfi_restore_state
45+
; CHECK-NEXT: mov w0, wzr
46+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
47+
; CHECK-NEXT: .cfi_def_cfa_offset 0
48+
; CHECK-NEXT: .cfi_restore w30
49+
; CHECK-NEXT: ret
50+
entry:
51+
switch i32 %x, label %if.end7 [
52+
i32 0, label %return
53+
i32 1, label %if.then2
54+
i32 2, label %if.then5
55+
]
56+
57+
if.then2:
58+
%call = tail call i32 @g1(i32 1)
59+
%add = add nsw i32 %call, 1
60+
br label %return
61+
62+
if.then5:
63+
%call6 = tail call i32 @g0(i32 2)
64+
%sub = sub nsw i32 1, %call6
65+
br label %return
66+
67+
if.end7:
68+
br label %return
69+
70+
return:
71+
%retval.0 = phi i32 [ %add, %if.then2 ], [ %sub, %if.then5 ], [ 0, %if.end7 ], [ 1, %entry ]
72+
ret i32 %retval.0
73+
}
74+
75+
declare i32 @g1(i32)
76+
77+
declare i32 @g0(i32)
78+
79+
define i32 @f1(i32 %x) #0 {
80+
; CHECK-LABEL: f1:
81+
; CHECK: // %bb.0: // %entry
82+
; CHECK-NEXT: cbz w0, .LBB1_2
83+
; CHECK-NEXT: // %bb.1: // %if.end
84+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
85+
; CHECK-NEXT: .cfi_def_cfa_offset 16
86+
; CHECK-NEXT: .cfi_offset w30, -16
87+
; CHECK-NEXT: bl g0
88+
; CHECK-NEXT: add w0, w0, #1
89+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
90+
; CHECK-NEXT: .cfi_def_cfa_offset 0
91+
; CHECK-NEXT: .cfi_restore w30
92+
; CHECK-NEXT: .LBB1_2: // %return
93+
; CHECK-NEXT: ret
94+
entry:
95+
%cmp = icmp eq i32 %x, 0
96+
br i1 %cmp, label %return, label %if.end
97+
98+
if.end:
99+
%call = tail call i32 @g0(i32 %x)
100+
%add = add nsw i32 %call, 1
101+
br label %return
102+
103+
return:
104+
%retval.0 = phi i32 [ %add, %if.end ], [ 0, %entry ]
105+
ret i32 %retval.0
106+
}
107+
108+
define i32 @f2(i32 %x) #0 {
109+
; CHECK-LABEL: f2:
110+
; CHECK: // %bb.0: // %entry
111+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
112+
; CHECK-NEXT: .cfi_def_cfa_offset 16
113+
; CHECK-NEXT: .cfi_offset w30, -16
114+
; CHECK-NEXT: .cfi_remember_state
115+
; CHECK-NEXT: cbz w0, .LBB2_2
116+
; CHECK-NEXT: // %bb.1: // %if.end
117+
; CHECK-NEXT: bl g1
118+
; CHECK-NEXT: mov w8, #1
119+
; CHECK-NEXT: sub w0, w8, w0
120+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
121+
; CHECK-NEXT: .cfi_def_cfa_offset 0
122+
; CHECK-NEXT: .cfi_restore w30
123+
; CHECK-NEXT: ret
124+
; CHECK-NEXT: .LBB2_2: // %if.then
125+
; CHECK-NEXT: .cfi_restore_state
126+
; CHECK-NEXT: bl g0
127+
; CHECK-NEXT: add w0, w0, #1
128+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
129+
; CHECK-NEXT: .cfi_def_cfa_offset 0
130+
; CHECK-NEXT: .cfi_restore w30
131+
; CHECK-NEXT: ret
132+
entry:
133+
%cmp = icmp eq i32 %x, 0
134+
br i1 %cmp, label %if.then, label %if.end
135+
136+
if.then:
137+
%call = tail call i32 @g0(i32 0)
138+
%add = add nsw i32 %call, 1
139+
br label %return
140+
141+
if.end:
142+
%call1 = tail call i32 @g1(i32 %x)
143+
%sub = sub nsw i32 1, %call1
144+
br label %return
145+
146+
return:
147+
%retval.0 = phi i32 [ %add, %if.then ], [ %sub, %if.end ]
148+
ret i32 %retval.0
149+
}
150+
151+
attributes #0 = { uwtable }

0 commit comments

Comments
 (0)