Skip to content

Commit 1a71668

Browse files
[AArch64] Fix stack probing clobbering flags (#81879)
Certain stack probing sequences might clobber flags, then we can't use a block as a prologue if the flags register is a live-in on entry to that block.
1 parent e3d4cac commit 1a71668

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,12 @@ bool AArch64FrameLowering::canUseAsPrologue(
10611061
return false;
10621062
}
10631063

1064+
// Certain stack probing sequences might clobber flags, then we can't use
1065+
// the block as a prologue if the flags register is a live-in.
1066+
if (MF->getInfo<AArch64FunctionInfo>()->hasStackProbing() &&
1067+
MBB.isLiveIn(AArch64::NZCV))
1068+
return false;
1069+
10641070
// Don't need a scratch register if we're not going to re-align the stack or
10651071
// emit stack probes.
10661072
if (!RegInfo->hasStackRealignment(*MF) && !TLI->hasInlineStackProbe(*MF))
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc %s --start-before=shrink-wrap --stop-after=prologepilog -o - | FileCheck %s
3+
--- |
4+
target triple = "aarch64-linux"
5+
6+
define void @f(i32 %n) #0 {
7+
entry:
8+
%a = alloca i8, i32 150000, align 8
9+
%c0 = icmp sle i32 %n, 1
10+
br i1 %c0, label %if.then1, label %exit
11+
12+
if.then1: ; preds = %entry
13+
%0 = icmp sle i32 %n, 1
14+
%v = select i1 %0, i32 0, i32 1
15+
call void @g(ptr %a, i32 %v)
16+
br label %exit
17+
18+
exit: ; preds = %if.then1, %entry
19+
ret void
20+
}
21+
22+
declare void @g(...)
23+
24+
attributes #0 = { nounwind "probe-stack"="inline-asm" "stack-probe-size"="4096" }
25+
26+
...
27+
---
28+
name: f
29+
alignment: 4
30+
tracksRegLiveness: true
31+
liveins:
32+
- { reg: '$w0', virtual-reg: '' }
33+
frameInfo:
34+
localFrameSize: 150000
35+
stack:
36+
- { id: 0, name: a, type: default, offset: 0, size: 150000, alignment: 8,
37+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
38+
local-offset: -150000, debug-info-variable: '', debug-info-expression: '',
39+
debug-info-location: '' }
40+
entry_values: []
41+
callSites: []
42+
debugValueSubstitutions: []
43+
constants: []
44+
machineFunctionInfo: {}
45+
body: |
46+
; CHECK-LABEL: name: f
47+
; CHECK: bb.0.entry:
48+
; CHECK-NEXT: successors: %bb.3(0x80000000)
49+
; CHECK-NEXT: liveins: $w0, $lr
50+
; CHECK-NEXT: {{ $}}
51+
; CHECK-NEXT: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store (s64) into %stack.2), (store (s64) into %stack.1)
52+
; CHECK-NEXT: $x9 = frame-setup SUBXri $sp, 36, 12
53+
; CHECK-NEXT: {{ $}}
54+
; CHECK-NEXT: bb.3.entry:
55+
; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.3(0x40000000)
56+
; CHECK-NEXT: liveins: $w0, $x9
57+
; CHECK-NEXT: {{ $}}
58+
; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 1, 12
59+
; CHECK-NEXT: frame-setup STRXui $xzr, $sp, 0
60+
; CHECK-NEXT: $xzr = frame-setup SUBSXrx64 $sp, $x9, 24, implicit-def $nzcv
61+
; CHECK-NEXT: frame-setup Bcc 1, %bb.3, implicit $nzcv
62+
; CHECK-NEXT: {{ $}}
63+
; CHECK-NEXT: bb.4.entry:
64+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
65+
; CHECK-NEXT: liveins: $w0
66+
; CHECK-NEXT: {{ $}}
67+
; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 2544, 0
68+
; CHECK-NEXT: frame-setup STRXui $xzr, $sp, 0
69+
; CHECK-NEXT: dead $wzr = SUBSWri killed renamable $w0, 1, 0, implicit-def $nzcv
70+
; CHECK-NEXT: Bcc 12, %bb.2, implicit $nzcv
71+
; CHECK-NEXT: B %bb.1
72+
; CHECK-NEXT: {{ $}}
73+
; CHECK-NEXT: bb.1.if.then1:
74+
; CHECK-NEXT: successors: %bb.2(0x80000000)
75+
; CHECK-NEXT: liveins: $nzcv
76+
; CHECK-NEXT: {{ $}}
77+
; CHECK-NEXT: renamable $w1 = CSINCWr $wzr, $wzr, 13, implicit killed $nzcv
78+
; CHECK-NEXT: $x0 = ADDXri $sp, 0, 0
79+
; CHECK-NEXT: BL @g, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit $w1, implicit-def $sp
80+
; CHECK-NEXT: {{ $}}
81+
; CHECK-NEXT: bb.2.exit:
82+
; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 36, 12
83+
; CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 2544, 0
84+
; CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 :: (load (s64) from %stack.2), (load (s64) from %stack.1)
85+
; CHECK-NEXT: RET_ReallyLR
86+
bb.0.entry:
87+
successors: %bb.1(0x40000000), %bb.2(0x40000000)
88+
liveins: $w0
89+
90+
dead $wzr = SUBSWri killed renamable $w0, 1, 0, implicit-def $nzcv
91+
Bcc 12, %bb.2, implicit $nzcv
92+
B %bb.1
93+
94+
bb.1.if.then1:
95+
successors: %bb.2(0x80000000)
96+
liveins: $nzcv
97+
98+
renamable $w1 = CSINCWr $wzr, $wzr, 13, implicit killed $nzcv
99+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
100+
$x0 = ADDXri %stack.0.a, 0, 0
101+
BL @g, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit $w1, implicit-def $sp
102+
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp
103+
104+
bb.2.exit:
105+
RET_ReallyLR
106+
107+
...

0 commit comments

Comments
 (0)