1 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all | FileCheck %s --check-prefixes=FP,LEAF-FP
2 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-FP
3 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=all -mattr=+aapcs-frame-chain-leaf | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-FP-AAPCS
4 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf | FileCheck %s --check-prefixes=FP,LEAF-NOFP
5 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-NOFP
6 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=non-leaf -mattr=+aapcs-frame-chain-leaf | FileCheck %s --check-prefixes=FP-AAPCS,LEAF-NOFP-AAPCS
7 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none | FileCheck %s --check-prefixes=NOFP,LEAF-NOFP
8 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none -mattr=+aapcs-frame-chain | FileCheck %s --check-prefixes=NOFP-AAPCS,LEAF-NOFP
9 ; RUN: llc -mtriple arm-arm-none-eabi -filetype asm -o - %s -frame-pointer=none -mattr=+aapcs-frame-chain-leaf | FileCheck %s --check-prefixes=NOFP-AAPCS,LEAF-NOFP-AAPCS
11 define dso_local noundef i32 @leaf(i32 noundef %0) {
12 ; LEAF-FP-LABEL: leaf:
14 ; LEAF-FP-NEXT: .pad #4
15 ; LEAF-FP-NEXT: sub sp, sp, #4
16 ; LEAF-FP-NEXT: str r0, [sp]
17 ; LEAF-FP-NEXT: add r0, r0, #4
18 ; LEAF-FP-NEXT: add sp, sp, #4
19 ; LEAF-FP-NEXT: mov pc, lr
21 ; LEAF-FP-AAPCS-LABEL: leaf:
22 ; LEAF-FP-AAPCS: @ %bb.0:
23 ; LEAF-FP-AAPCS-NEXT: .save {r11, lr}
24 ; LEAF-FP-AAPCS-NEXT: push {r11, lr}
25 ; LEAF-FP-AAPCS-NEXT: .setfp r11, sp
26 ; LEAF-FP-AAPCS-NEXT: mov r11, sp
27 ; LEAF-FP-AAPCS-NEXT: push {r0}
28 ; LEAF-FP-AAPCS-NEXT: add r0, r0, #4
29 ; LEAF-FP-AAPCS-NEXT: mov sp, r11
30 ; LEAF-FP-AAPCS-NEXT: pop {r11, lr}
31 ; LEAF-FP-AAPCS-NEXT: mov pc, lr
33 ; LEAF-NOFP-LABEL: leaf:
35 ; LEAF-NOFP-NEXT: .pad #4
36 ; LEAF-NOFP-NEXT: sub sp, sp, #4
37 ; LEAF-NOFP-NEXT: str r0, [sp]
38 ; LEAF-NOFP-NEXT: add r0, r0, #4
39 ; LEAF-NOFP-NEXT: add sp, sp, #4
40 ; LEAF-NOFP-NEXT: mov pc, lr
42 ; LEAF-NOFP-AAPCS-LABEL: leaf:
43 ; LEAF-NOFP-AAPCS: @ %bb.0:
44 ; LEAF-NOFP-AAPCS-NEXT: .pad #4
45 ; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, #4
46 ; LEAF-NOFP-AAPCS-NEXT: str r0, [sp]
47 ; LEAF-NOFP-AAPCS-NEXT: add r0, r0, #4
48 ; LEAF-NOFP-AAPCS-NEXT: add sp, sp, #4
49 ; LEAF-NOFP-AAPCS-NEXT: mov pc, lr
50 %2 = alloca i32, align 4
51 store i32 %0, ptr %2, align 4
52 %3 = load i32, ptr %2, align 4
53 %4 = add nsw i32 %3, 4
57 define dso_local noundef i32 @non_leaf(i32 noundef %0) {
60 ; FP-NEXT: .save {r11, lr}
61 ; FP-NEXT: push {r11, lr}
62 ; FP-NEXT: .setfp r11, sp
63 ; FP-NEXT: mov r11, sp
65 ; FP-NEXT: sub sp, sp, #8
66 ; FP-NEXT: str r0, [sp, #4]
68 ; FP-NEXT: add r0, r0, #1
69 ; FP-NEXT: mov sp, r11
70 ; FP-NEXT: pop {r11, lr}
73 ; FP-AAPCS-LABEL: non_leaf:
75 ; FP-AAPCS-NEXT: .save {r11, lr}
76 ; FP-AAPCS-NEXT: push {r11, lr}
77 ; FP-AAPCS-NEXT: .setfp r11, sp
78 ; FP-AAPCS-NEXT: mov r11, sp
79 ; FP-AAPCS-NEXT: .pad #8
80 ; FP-AAPCS-NEXT: sub sp, sp, #8
81 ; FP-AAPCS-NEXT: str r0, [sp, #4]
82 ; FP-AAPCS-NEXT: bl leaf
83 ; FP-AAPCS-NEXT: add r0, r0, #1
84 ; FP-AAPCS-NEXT: mov sp, r11
85 ; FP-AAPCS-NEXT: pop {r11, lr}
86 ; FP-AAPCS-NEXT: mov pc, lr
88 ; NOFP-LABEL: non_leaf:
90 ; NOFP-NEXT: .save {r11, lr}
91 ; NOFP-NEXT: push {r11, lr}
93 ; NOFP-NEXT: sub sp, sp, #8
94 ; NOFP-NEXT: str r0, [sp, #4]
96 ; NOFP-NEXT: add r0, r0, #1
97 ; NOFP-NEXT: add sp, sp, #8
98 ; NOFP-NEXT: pop {r11, lr}
99 ; NOFP-NEXT: mov pc, lr
101 ; NOFP-AAPCS-LABEL: non_leaf:
102 ; NOFP-AAPCS: @ %bb.0:
103 ; NOFP-AAPCS-NEXT: .save {r11, lr}
104 ; NOFP-AAPCS-NEXT: push {r11, lr}
105 ; NOFP-AAPCS-NEXT: .pad #8
106 ; NOFP-AAPCS-NEXT: sub sp, sp, #8
107 ; NOFP-AAPCS-NEXT: str r0, [sp, #4]
108 ; NOFP-AAPCS-NEXT: bl leaf
109 ; NOFP-AAPCS-NEXT: add r0, r0, #1
110 ; NOFP-AAPCS-NEXT: add sp, sp, #8
111 ; NOFP-AAPCS-NEXT: pop {r11, lr}
112 ; NOFP-AAPCS-NEXT: mov pc, lr
113 %2 = alloca i32, align 4
114 store i32 %0, ptr %2, align 4
115 %3 = load i32, ptr %2, align 4
116 %4 = call noundef i32 @leaf(i32 noundef %3)
117 %5 = add nsw i32 %4, 1
121 declare ptr @llvm.stacksave()
122 define dso_local void @required_fp(i32 %0, i32 %1) {
123 ; LEAF-FP-LABEL: required_fp:
125 ; LEAF-FP-NEXT: .save {r4, r5, r11, lr}
126 ; LEAF-FP-NEXT: push {r4, r5, r11, lr}
127 ; LEAF-FP-NEXT: .setfp r11, sp, #8
128 ; LEAF-FP-NEXT: add r11, sp, #8
129 ; LEAF-FP-NEXT: .pad #24
130 ; LEAF-FP-NEXT: sub sp, sp, #24
131 ; LEAF-FP-NEXT: str r1, [r11, #-16]
132 ; LEAF-FP-NEXT: mov r1, #7
133 ; LEAF-FP-NEXT: add r1, r1, r0, lsl #2
134 ; LEAF-FP-NEXT: str r0, [r11, #-12]
135 ; LEAF-FP-NEXT: bic r1, r1, #7
136 ; LEAF-FP-NEXT: str sp, [r11, #-24]
137 ; LEAF-FP-NEXT: sub sp, sp, r1
138 ; LEAF-FP-NEXT: mov r1, #0
139 ; LEAF-FP-NEXT: str r0, [r11, #-32]
140 ; LEAF-FP-NEXT: str r1, [r11, #-28]
141 ; LEAF-FP-NEXT: sub sp, r11, #8
142 ; LEAF-FP-NEXT: pop {r4, r5, r11, lr}
143 ; LEAF-FP-NEXT: mov pc, lr
145 ; LEAF-FP-AAPCS-LABEL: required_fp:
146 ; LEAF-FP-AAPCS: @ %bb.0:
147 ; LEAF-FP-AAPCS-NEXT: .save {r4, r5, r11, lr}
148 ; LEAF-FP-AAPCS-NEXT: push {r4, r5, r11, lr}
149 ; LEAF-FP-AAPCS-NEXT: .setfp r11, sp, #8
150 ; LEAF-FP-AAPCS-NEXT: add r11, sp, #8
151 ; LEAF-FP-AAPCS-NEXT: .pad #24
152 ; LEAF-FP-AAPCS-NEXT: sub sp, sp, #24
153 ; LEAF-FP-AAPCS-NEXT: str r1, [r11, #-16]
154 ; LEAF-FP-AAPCS-NEXT: mov r1, #7
155 ; LEAF-FP-AAPCS-NEXT: add r1, r1, r0, lsl #2
156 ; LEAF-FP-AAPCS-NEXT: str r0, [r11, #-12]
157 ; LEAF-FP-AAPCS-NEXT: bic r1, r1, #7
158 ; LEAF-FP-AAPCS-NEXT: str sp, [r11, #-24]
159 ; LEAF-FP-AAPCS-NEXT: sub sp, sp, r1
160 ; LEAF-FP-AAPCS-NEXT: mov r1, #0
161 ; LEAF-FP-AAPCS-NEXT: str r0, [r11, #-32]
162 ; LEAF-FP-AAPCS-NEXT: str r1, [r11, #-28]
163 ; LEAF-FP-AAPCS-NEXT: sub sp, r11, #8
164 ; LEAF-FP-AAPCS-NEXT: pop {r4, r5, r11, lr}
165 ; LEAF-FP-AAPCS-NEXT: mov pc, lr
167 ; LEAF-NOFP-LABEL: required_fp:
168 ; LEAF-NOFP: @ %bb.0:
169 ; LEAF-NOFP-NEXT: .save {r4, r5, r11}
170 ; LEAF-NOFP-NEXT: push {r4, r5, r11}
171 ; LEAF-NOFP-NEXT: .setfp r11, sp, #8
172 ; LEAF-NOFP-NEXT: add r11, sp, #8
173 ; LEAF-NOFP-NEXT: .pad #20
174 ; LEAF-NOFP-NEXT: sub sp, sp, #20
175 ; LEAF-NOFP-NEXT: str r1, [r11, #-16]
176 ; LEAF-NOFP-NEXT: mov r1, #7
177 ; LEAF-NOFP-NEXT: add r1, r1, r0, lsl #2
178 ; LEAF-NOFP-NEXT: str r0, [r11, #-12]
179 ; LEAF-NOFP-NEXT: bic r1, r1, #7
180 ; LEAF-NOFP-NEXT: str sp, [r11, #-20]
181 ; LEAF-NOFP-NEXT: sub sp, sp, r1
182 ; LEAF-NOFP-NEXT: mov r1, #0
183 ; LEAF-NOFP-NEXT: str r0, [r11, #-28]
184 ; LEAF-NOFP-NEXT: str r1, [r11, #-24]
185 ; LEAF-NOFP-NEXT: sub sp, r11, #8
186 ; LEAF-NOFP-NEXT: pop {r4, r5, r11}
187 ; LEAF-NOFP-NEXT: mov pc, lr
189 ; LEAF-NOFP-AAPCS-LABEL: required_fp:
190 ; LEAF-NOFP-AAPCS: @ %bb.0:
191 ; LEAF-NOFP-AAPCS-NEXT: .save {r4, r5, r11, lr}
192 ; LEAF-NOFP-AAPCS-NEXT: push {r4, r5, r11, lr}
193 ; LEAF-NOFP-AAPCS-NEXT: .setfp r11, sp, #8
194 ; LEAF-NOFP-AAPCS-NEXT: add r11, sp, #8
195 ; LEAF-NOFP-AAPCS-NEXT: .pad #24
196 ; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, #24
197 ; LEAF-NOFP-AAPCS-NEXT: str r1, [r11, #-16]
198 ; LEAF-NOFP-AAPCS-NEXT: mov r1, #7
199 ; LEAF-NOFP-AAPCS-NEXT: add r1, r1, r0, lsl #2
200 ; LEAF-NOFP-AAPCS-NEXT: str r0, [r11, #-12]
201 ; LEAF-NOFP-AAPCS-NEXT: bic r1, r1, #7
202 ; LEAF-NOFP-AAPCS-NEXT: str sp, [r11, #-24]
203 ; LEAF-NOFP-AAPCS-NEXT: sub sp, sp, r1
204 ; LEAF-NOFP-AAPCS-NEXT: mov r1, #0
205 ; LEAF-NOFP-AAPCS-NEXT: str r0, [r11, #-32]
206 ; LEAF-NOFP-AAPCS-NEXT: str r1, [r11, #-28]
207 ; LEAF-NOFP-AAPCS-NEXT: sub sp, r11, #8
208 ; LEAF-NOFP-AAPCS-NEXT: pop {r4, r5, r11, lr}
209 ; LEAF-NOFP-AAPCS-NEXT: mov pc, lr
210 %3 = alloca i32, align 4
211 %4 = alloca i32, align 4
212 %5 = alloca ptr, align 8
213 %6 = alloca i64, align 8
214 store i32 %0, ptr %3, align 4
215 store i32 %1, ptr %4, align 4
216 %7 = load i32, ptr %3, align 4
217 %8 = zext i32 %7 to i64
218 %9 = call ptr @llvm.stacksave()
219 store ptr %9, ptr %5, align 8
220 %10 = alloca i32, i64 %8, align 4
221 store i64 %8, ptr %6, align 8