Skip to content

Commit acd2580

Browse files
author
Jessica Paquette
committed
[MachineOutliner][AArch64] Save + restore LR in noreturn functions
Conservatively always save + restore LR in noreturn functions. These functions do not end in a RET, and so they aren't guaranteed to have an instruction which uses LR in any way. So, as a result, you can end up in unfortunate situations where you can't backtrace out of these functions in a debugger. Remove the old noreturn test, and add a new one which is more descriptive. Remove the restriction that we can't outline from noreturn functions as well since we now do the right thing.
1 parent afa8211 commit acd2580

File tree

4 files changed

+114
-63
lines changed

4 files changed

+114
-63
lines changed

llvm/lib/CodeGen/MachineOutliner.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,12 +1306,6 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M,
13061306
if (F.empty())
13071307
continue;
13081308

1309-
// Disable outlining from noreturn functions right now. Noreturn requires
1310-
// special handling for the case where what we are outlining could be a
1311-
// tail call.
1312-
if (F.hasFnAttribute(Attribute::NoReturn))
1313-
continue;
1314-
13151309
// There's something in F. Check if it has a MachineFunction associated with
13161310
// it.
13171311
MachineFunction *MF = MMI.getMachineFunction(F);

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5868,11 +5868,21 @@ outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo(
58685868
unsigned NumBytesNoStackCalls = 0;
58695869
std::vector<outliner::Candidate> CandidatesWithoutStackFixups;
58705870

5871+
// Check if we have to save LR.
58715872
for (outliner::Candidate &C : RepeatedSequenceLocs) {
58725873
C.initLRU(TRI);
58735874

5875+
// If we have a noreturn caller, then we're going to be conservative and
5876+
// say that we have to save LR. If we don't have a ret at the end of the
5877+
// block, then we can't reason about liveness accurately.
5878+
//
5879+
// FIXME: We can probably do better than always disabling this in
5880+
// noreturn functions by fixing up the liveness info.
5881+
bool IsNoReturn =
5882+
C.getMF()->getFunction().hasFnAttribute(Attribute::NoReturn);
5883+
58745884
// Is LR available? If so, we don't need a save.
5875-
if (C.LRU.available(AArch64::LR)) {
5885+
if (C.LRU.available(AArch64::LR) && !IsNoReturn) {
58765886
NumBytesNoStackCalls += 4;
58775887
C.setCallInfo(MachineOutlinerNoLRSave, 4);
58785888
CandidatesWithoutStackFixups.push_back(C);
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=aarch64-unknown-unknown -run-pass=machine-outliner -verify-machineinstrs %s -o - | FileCheck %s
3+
4+
# Verify that we save + restore LR around calls to outlined functions from
5+
# noreturn parents. LR isn't actually used, but debuggers need LR in this case
6+
# to get a backtrace.
7+
8+
--- |
9+
define void @save_lr_1() #0 { ret void }
10+
define void @save_lr_2() #0 { ret void }
11+
define void @save_lr_3() #0 { ret void }
12+
define void @save_lr_4() #0 { ret void }
13+
attributes #0 = { noredzone noreturn }
14+
...
15+
---
16+
17+
name: save_lr_1
18+
alignment: 4
19+
tracksRegLiveness: true
20+
frameInfo:
21+
maxAlignment: 1
22+
maxCallFrameSize: 0
23+
machineFunctionInfo: {}
24+
body: |
25+
bb.0:
26+
liveins: $lr
27+
; CHECK-LABEL: name: save_lr_1
28+
; CHECK: liveins: $lr
29+
; CHECK: $x0 = ORRXrs $xzr, $lr, 0
30+
; CHECK: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $lr, implicit-def $w3, implicit-def $w4, implicit-def $w5, implicit-def $w6
31+
; CHECK: $lr = ORRXrs $xzr, $x0, 0
32+
$w3 = ORRWri $wzr, 1
33+
$w4 = ORRWri $wzr, 1
34+
BRK 1
35+
$w5 = ORRWri $wzr, 1
36+
$w6 = ORRWri $wzr, 1
37+
...
38+
---
39+
name: save_lr_2
40+
alignment: 4
41+
tracksRegLiveness: true
42+
frameInfo:
43+
maxAlignment: 1
44+
maxCallFrameSize: 0
45+
machineFunctionInfo: {}
46+
body: |
47+
bb.0:
48+
liveins: $lr
49+
; CHECK-LABEL: name: save_lr_2
50+
; CHECK: liveins: $lr
51+
; CHECK: $x0 = ORRXrs $xzr, $lr, 0
52+
; CHECK: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $lr, implicit-def $w3, implicit-def $w4, implicit-def $w5, implicit-def $w6
53+
; CHECK: $lr = ORRXrs $xzr, $x0, 0
54+
$w3 = ORRWri $wzr, 1
55+
$w4 = ORRWri $wzr, 1
56+
BRK 1
57+
$w5 = ORRWri $wzr, 1
58+
$w6 = ORRWri $wzr, 1
59+
...
60+
---
61+
name: save_lr_3
62+
alignment: 4
63+
tracksRegLiveness: true
64+
frameInfo:
65+
maxAlignment: 1
66+
maxCallFrameSize: 0
67+
machineFunctionInfo: {}
68+
body: |
69+
bb.0:
70+
liveins: $lr
71+
; CHECK-LABEL: name: save_lr_3
72+
; CHECK: liveins: $lr
73+
; CHECK: $x0 = ORRXrs $xzr, $lr, 0
74+
; CHECK: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $lr, implicit-def $w3, implicit-def $w4, implicit-def $w5, implicit-def $w6
75+
; CHECK: $lr = ORRXrs $xzr, $x0, 0
76+
$w3 = ORRWri $wzr, 1
77+
$w4 = ORRWri $wzr, 1
78+
BRK 1
79+
$w5 = ORRWri $wzr, 1
80+
$w6 = ORRWri $wzr, 1
81+
...
82+
---
83+
name: save_lr_4
84+
alignment: 4
85+
tracksRegLiveness: true
86+
frameInfo:
87+
maxAlignment: 1
88+
maxCallFrameSize: 0
89+
machineFunctionInfo: {}
90+
body: |
91+
bb.0:
92+
liveins: $lr
93+
; CHECK-LABEL: name: save_lr_4
94+
; CHECK: liveins: $lr
95+
; CHECK: $x0 = ORRXrs $xzr, $lr, 0
96+
; CHECK: BL @OUTLINED_FUNCTION_0, implicit-def $lr, implicit $sp, implicit-def $lr, implicit-def $lr, implicit-def $w3, implicit-def $w4, implicit-def $w5, implicit-def $w6
97+
; CHECK: $lr = ORRXrs $xzr, $x0, 0
98+
$w3 = ORRWri $wzr, 1
99+
$w4 = ORRWri $wzr, 1
100+
BRK 1
101+
$w5 = ORRWri $wzr, 1
102+
$w6 = ORRWri $wzr, 1
103+
...

llvm/test/CodeGen/AArch64/machine-outliner-noreturn.mir

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)