1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc %s -o - -mtriple=thumbv8m.base | \
3 ; RUN: FileCheck %s --check-prefix=CHECK-8B
4 ; RUN: llc %s -o - -mtriple=thumbebv8m.base | \
5 ; RUN: FileCheck %s --check-prefix=CHECK-8B
6 ; RUN: llc %s -o - -mtriple=thumbv8m.main | \
7 ; RUN: FileCheck %s --check-prefix=CHECK-8M
8 ; RUN: llc %s -o - -mtriple=thumbebv8m.main | \
9 ; RUN: FileCheck %s --check-prefix=CHECK-8M
11 ; RUN: llc %s -o - -mtriple=thumbv8.1m.main | \
12 ; RUN: FileCheck %s --check-prefix=CHECK-81M
13 ; RUN: llc %s -o - -mtriple=thumbebv8.1m.main | \
14 ; RUN: FileCheck %s --check-prefix=CHECK-81M
16 define void @func1(void ()* nocapture %fptr) #0 {
17 ; CHECK-8B-LABEL: func1:
18 ; CHECK-8B: @ %bb.0: @ %entry
19 ; CHECK-8B-NEXT: push {r7, lr}
20 ; CHECK-8B-NEXT: push {r4, r5, r6, r7}
21 ; CHECK-8B-NEXT: mov r7, r11
22 ; CHECK-8B-NEXT: mov r6, r10
23 ; CHECK-8B-NEXT: mov r5, r9
24 ; CHECK-8B-NEXT: mov r4, r8
25 ; CHECK-8B-NEXT: push {r4, r5, r6, r7}
26 ; CHECK-8B-NEXT: mov r1, #1
27 ; CHECK-8B-NEXT: bics r0, r1
28 ; CHECK-8B-NEXT: mov r1, r0
29 ; CHECK-8B-NEXT: mov r2, r0
30 ; CHECK-8B-NEXT: mov r3, r0
31 ; CHECK-8B-NEXT: mov r4, r0
32 ; CHECK-8B-NEXT: mov r5, r0
33 ; CHECK-8B-NEXT: mov r6, r0
34 ; CHECK-8B-NEXT: mov r7, r0
35 ; CHECK-8B-NEXT: mov r8, r0
36 ; CHECK-8B-NEXT: mov r9, r0
37 ; CHECK-8B-NEXT: mov r10, r0
38 ; CHECK-8B-NEXT: mov r11, r0
39 ; CHECK-8B-NEXT: mov r12, r0
40 ; CHECK-8B-NEXT: msr apsr, r0
41 ; CHECK-8B-NEXT: blxns r0
42 ; CHECK-8B-NEXT: pop {r4, r5, r6, r7}
43 ; CHECK-8B-NEXT: mov r8, r4
44 ; CHECK-8B-NEXT: mov r9, r5
45 ; CHECK-8B-NEXT: mov r10, r6
46 ; CHECK-8B-NEXT: mov r11, r7
47 ; CHECK-8B-NEXT: pop {r4, r5, r6, r7}
48 ; CHECK-8B-NEXT: pop {r7}
49 ; CHECK-8B-NEXT: pop {r0}
50 ; CHECK-8B-NEXT: mov lr, r0
51 ; CHECK-8B-NEXT: mov r0, lr
52 ; CHECK-8B-NEXT: mov r1, lr
53 ; CHECK-8B-NEXT: mov r2, lr
54 ; CHECK-8B-NEXT: mov r3, lr
55 ; CHECK-8B-NEXT: mov r12, lr
56 ; CHECK-8B-NEXT: msr apsr, lr
57 ; CHECK-8B-NEXT: bxns lr
59 ; CHECK-8M-LABEL: func1:
60 ; CHECK-8M: @ %bb.0: @ %entry
61 ; CHECK-8M-NEXT: push {r7, lr}
62 ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
63 ; CHECK-8M-NEXT: bic r0, r0, #1
64 ; CHECK-8M-NEXT: msr apsr_nzcvq, r0
65 ; CHECK-8M-NEXT: mov r1, r0
66 ; CHECK-8M-NEXT: mov r2, r0
67 ; CHECK-8M-NEXT: mov r3, r0
68 ; CHECK-8M-NEXT: mov r4, r0
69 ; CHECK-8M-NEXT: mov r5, r0
70 ; CHECK-8M-NEXT: mov r6, r0
71 ; CHECK-8M-NEXT: mov r7, r0
72 ; CHECK-8M-NEXT: mov r8, r0
73 ; CHECK-8M-NEXT: mov r9, r0
74 ; CHECK-8M-NEXT: mov r10, r0
75 ; CHECK-8M-NEXT: mov r11, r0
76 ; CHECK-8M-NEXT: mov r12, r0
77 ; CHECK-8M-NEXT: blxns r0
78 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
79 ; CHECK-8M-NEXT: pop.w {r7, lr}
80 ; CHECK-8M-NEXT: mov r0, lr
81 ; CHECK-8M-NEXT: mov r1, lr
82 ; CHECK-8M-NEXT: mov r2, lr
83 ; CHECK-8M-NEXT: mov r3, lr
84 ; CHECK-8M-NEXT: mov r12, lr
85 ; CHECK-8M-NEXT: msr apsr_nzcvq, lr
86 ; CHECK-8M-NEXT: bxns lr
88 ; CHECK-81M-LABEL: func1:
89 ; CHECK-81M: @ %bb.0: @ %entry
90 ; CHECK-81M-NEXT: vstr fpcxtns, [sp, #-4]!
91 ; CHECK-81M-NEXT: push {r7, lr}
92 ; CHECK-81M-NEXT: sub sp, #4
93 ; CHECK-81M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
94 ; CHECK-81M-NEXT: bic r0, r0, #1
95 ; CHECK-81M-NEXT: sub sp, #136
96 ; CHECK-81M-NEXT: vlstm sp
97 ; CHECK-81M-NEXT: clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
98 ; CHECK-81M-NEXT: blxns r0
99 ; CHECK-81M-NEXT: vlldm sp
100 ; CHECK-81M-NEXT: add sp, #136
101 ; CHECK-81M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
102 ; CHECK-81M-NEXT: add sp, #4
103 ; CHECK-81M-NEXT: pop.w {r7, lr}
104 ; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
105 ; CHECK-81M-NEXT: vldr fpcxtns, [sp], #4
106 ; CHECK-81M-NEXT: clrm {r0, r1, r2, r3, r12, apsr}
107 ; CHECK-81M-NEXT: bxns lr
113 attributes #0 = { "cmse_nonsecure_entry" nounwind }
114 attributes #1 = { "cmse_nonsecure_call" nounwind }
116 define void @func2(void ()* nocapture %fptr) #2 {
117 ; CHECK-8B-LABEL: func2:
118 ; CHECK-8B: @ %bb.0: @ %entry
119 ; CHECK-8B-NEXT: push {r7, lr}
120 ; CHECK-8B-NEXT: push {r4, r5, r6, r7}
121 ; CHECK-8B-NEXT: mov r7, r11
122 ; CHECK-8B-NEXT: mov r6, r10
123 ; CHECK-8B-NEXT: mov r5, r9
124 ; CHECK-8B-NEXT: mov r4, r8
125 ; CHECK-8B-NEXT: push {r4, r5, r6, r7}
126 ; CHECK-8B-NEXT: mov r1, #1
127 ; CHECK-8B-NEXT: bics r0, r1
128 ; CHECK-8B-NEXT: mov r1, r0
129 ; CHECK-8B-NEXT: mov r2, r0
130 ; CHECK-8B-NEXT: mov r3, r0
131 ; CHECK-8B-NEXT: mov r4, r0
132 ; CHECK-8B-NEXT: mov r5, r0
133 ; CHECK-8B-NEXT: mov r6, r0
134 ; CHECK-8B-NEXT: mov r7, r0
135 ; CHECK-8B-NEXT: mov r8, r0
136 ; CHECK-8B-NEXT: mov r9, r0
137 ; CHECK-8B-NEXT: mov r10, r0
138 ; CHECK-8B-NEXT: mov r11, r0
139 ; CHECK-8B-NEXT: mov r12, r0
140 ; CHECK-8B-NEXT: msr apsr, r0
141 ; CHECK-8B-NEXT: blxns r0
142 ; CHECK-8B-NEXT: pop {r4, r5, r6, r7}
143 ; CHECK-8B-NEXT: mov r8, r4
144 ; CHECK-8B-NEXT: mov r9, r5
145 ; CHECK-8B-NEXT: mov r10, r6
146 ; CHECK-8B-NEXT: mov r11, r7
147 ; CHECK-8B-NEXT: pop {r4, r5, r6, r7}
148 ; CHECK-8B-NEXT: pop {r7, pc}
150 ; CHECK-8M-LABEL: func2:
151 ; CHECK-8M: @ %bb.0: @ %entry
152 ; CHECK-8M-NEXT: push {r7, lr}
153 ; CHECK-8M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
154 ; CHECK-8M-NEXT: bic r0, r0, #1
155 ; CHECK-8M-NEXT: msr apsr_nzcvq, r0
156 ; CHECK-8M-NEXT: mov r1, r0
157 ; CHECK-8M-NEXT: mov r2, r0
158 ; CHECK-8M-NEXT: mov r3, r0
159 ; CHECK-8M-NEXT: mov r4, r0
160 ; CHECK-8M-NEXT: mov r5, r0
161 ; CHECK-8M-NEXT: mov r6, r0
162 ; CHECK-8M-NEXT: mov r7, r0
163 ; CHECK-8M-NEXT: mov r8, r0
164 ; CHECK-8M-NEXT: mov r9, r0
165 ; CHECK-8M-NEXT: mov r10, r0
166 ; CHECK-8M-NEXT: mov r11, r0
167 ; CHECK-8M-NEXT: mov r12, r0
168 ; CHECK-8M-NEXT: blxns r0
169 ; CHECK-8M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
170 ; CHECK-8M-NEXT: pop {r7, pc}
172 ; CHECK-81M-LABEL: func2:
173 ; CHECK-81M: @ %bb.0: @ %entry
174 ; CHECK-81M-NEXT: push {r7, lr}
175 ; CHECK-81M-NEXT: push.w {r4, r5, r6, r7, r8, r9, r10, r11}
176 ; CHECK-81M-NEXT: bic r0, r0, #1
177 ; CHECK-81M-NEXT: sub sp, #136
178 ; CHECK-81M-NEXT: vlstm sp
179 ; CHECK-81M-NEXT: clrm {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, apsr}
180 ; CHECK-81M-NEXT: blxns r0
181 ; CHECK-81M-NEXT: vlldm sp
182 ; CHECK-81M-NEXT: add sp, #136
183 ; CHECK-81M-NEXT: pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
184 ; CHECK-81M-NEXT: pop {r7, pc}
186 tail call void %fptr() #3
190 attributes #2 = { nounwind }
191 attributes #3 = { "cmse_nonsecure_call" nounwind }
193 define void @func3() #4 {
194 ; CHECK-8B-LABEL: func3:
195 ; CHECK-8B: @ %bb.0: @ %entry
196 ; CHECK-8B-NEXT: mov r0, lr
197 ; CHECK-8B-NEXT: mov r1, lr
198 ; CHECK-8B-NEXT: mov r2, lr
199 ; CHECK-8B-NEXT: mov r3, lr
200 ; CHECK-8B-NEXT: mov r12, lr
201 ; CHECK-8B-NEXT: msr apsr, lr
202 ; CHECK-8B-NEXT: bxns lr
204 ; CHECK-8M-LABEL: func3:
205 ; CHECK-8M: @ %bb.0: @ %entry
206 ; CHECK-8M-NEXT: mov r0, lr
207 ; CHECK-8M-NEXT: mov r1, lr
208 ; CHECK-8M-NEXT: mov r2, lr
209 ; CHECK-8M-NEXT: mov r3, lr
210 ; CHECK-8M-NEXT: mov r12, lr
211 ; CHECK-8M-NEXT: msr apsr_nzcvq, lr
212 ; CHECK-8M-NEXT: bxns lr
214 ; CHECK-81M-LABEL: func3:
215 ; CHECK-81M: @ %bb.0: @ %entry
216 ; CHECK-81M-NEXT: vstr fpcxtns, [sp, #-4]!
217 ; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
218 ; CHECK-81M-NEXT: vldr fpcxtns, [sp], #4
219 ; CHECK-81M-NEXT: clrm {r0, r1, r2, r3, r12, apsr}
220 ; CHECK-81M-NEXT: bxns lr
225 define void @func4() #4 {
226 ; CHECK-8B-LABEL: func4:
227 ; CHECK-8B: @ %bb.0: @ %entry
228 ; CHECK-8B-NEXT: push {r7, lr}
229 ; CHECK-8B-NEXT: bl func3
230 ; CHECK-8B-NEXT: pop {r7}
231 ; CHECK-8B-NEXT: pop {r0}
232 ; CHECK-8B-NEXT: mov lr, r0
233 ; CHECK-8B-NEXT: mov r0, lr
234 ; CHECK-8B-NEXT: mov r1, lr
235 ; CHECK-8B-NEXT: mov r2, lr
236 ; CHECK-8B-NEXT: mov r3, lr
237 ; CHECK-8B-NEXT: mov r12, lr
238 ; CHECK-8B-NEXT: msr apsr, lr
239 ; CHECK-8B-NEXT: bxns lr
241 ; CHECK-8M-LABEL: func4:
242 ; CHECK-8M: @ %bb.0: @ %entry
243 ; CHECK-8M-NEXT: push {r7, lr}
244 ; CHECK-8M-NEXT: bl func3
245 ; CHECK-8M-NEXT: pop.w {r7, lr}
246 ; CHECK-8M-NEXT: mov r0, lr
247 ; CHECK-8M-NEXT: mov r1, lr
248 ; CHECK-8M-NEXT: mov r2, lr
249 ; CHECK-8M-NEXT: mov r3, lr
250 ; CHECK-8M-NEXT: mov r12, lr
251 ; CHECK-8M-NEXT: msr apsr_nzcvq, lr
252 ; CHECK-8M-NEXT: bxns lr
254 ; CHECK-81M-LABEL: func4:
255 ; CHECK-81M: @ %bb.0: @ %entry
256 ; CHECK-81M-NEXT: vstr fpcxtns, [sp, #-4]!
257 ; CHECK-81M-NEXT: push {r7, lr}
258 ; CHECK-81M-NEXT: sub sp, #4
259 ; CHECK-81M-NEXT: bl func3
260 ; CHECK-81M-NEXT: add sp, #4
261 ; CHECK-81M-NEXT: pop.w {r7, lr}
262 ; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
263 ; CHECK-81M-NEXT: vldr fpcxtns, [sp], #4
264 ; CHECK-81M-NEXT: clrm {r0, r1, r2, r3, r12, apsr}
265 ; CHECK-81M-NEXT: bxns lr
267 tail call void @func3() #5
271 declare void @func51(i8 *);
273 define void @func5() #4 {
274 ; CHECK-8B-LABEL: func5:
276 ; CHECK-8B-NEXT: push {r4, r6, r7, lr}
277 ; CHECK-8B-NEXT: add r7, sp, #8
278 ; CHECK-8B-NEXT: sub sp, #16
279 ; CHECK-8B-NEXT: mov r4, sp
280 ; CHECK-8B-NEXT: lsrs r4, r4, #4
281 ; CHECK-8B-NEXT: lsls r4, r4, #4
282 ; CHECK-8B-NEXT: mov sp, r4
283 ; CHECK-8B-NEXT: mov r0, sp
284 ; CHECK-8B-NEXT: bl func51
285 ; CHECK-8B-NEXT: subs r4, r7, #7
286 ; CHECK-8B-NEXT: subs r4, #1
287 ; CHECK-8B-NEXT: mov sp, r4
288 ; CHECK-8B-NEXT: pop {r4, r6, r7}
289 ; CHECK-8B-NEXT: pop {r0}
290 ; CHECK-8B-NEXT: mov lr, r0
291 ; CHECK-8B-NEXT: mov r0, lr
292 ; CHECK-8B-NEXT: mov r1, lr
293 ; CHECK-8B-NEXT: mov r2, lr
294 ; CHECK-8B-NEXT: mov r3, lr
295 ; CHECK-8B-NEXT: mov r12, lr
296 ; CHECK-8B-NEXT: msr apsr, lr
297 ; CHECK-8B-NEXT: bxns lr
299 ; CHECK-8M-LABEL: func5:
301 ; CHECK-8M-NEXT: push {r4, r6, r7, lr}
302 ; CHECK-8M-NEXT: add r7, sp, #8
303 ; CHECK-8M-NEXT: sub sp, #16
304 ; CHECK-8M-NEXT: mov r4, sp
305 ; CHECK-8M-NEXT: bfc r4, #0, #4
306 ; CHECK-8M-NEXT: mov sp, r4
307 ; CHECK-8M-NEXT: mov r0, sp
308 ; CHECK-8M-NEXT: bl func51
309 ; CHECK-8M-NEXT: sub.w r4, r7, #8
310 ; CHECK-8M-NEXT: mov sp, r4
311 ; CHECK-8M-NEXT: pop.w {r4, r6, r7, lr}
312 ; CHECK-8M-NEXT: mov r0, lr
313 ; CHECK-8M-NEXT: mov r1, lr
314 ; CHECK-8M-NEXT: mov r2, lr
315 ; CHECK-8M-NEXT: mov r3, lr
316 ; CHECK-8M-NEXT: mov r12, lr
317 ; CHECK-8M-NEXT: msr apsr_nzcvq, lr
318 ; CHECK-8M-NEXT: bxns lr
320 ; CHECK-81M-LABEL: func5:
321 ; CHECK-81M: @ %bb.0:
322 ; CHECK-81M-NEXT: vstr fpcxtns, [sp, #-4]!
323 ; CHECK-81M-NEXT: push {r4, r6, r7, lr}
324 ; CHECK-81M-NEXT: add r7, sp, #8
325 ; CHECK-81M-NEXT: sub sp, #12
326 ; CHECK-81M-NEXT: mov r4, sp
327 ; CHECK-81M-NEXT: bfc r4, #0, #4
328 ; CHECK-81M-NEXT: mov sp, r4
329 ; CHECK-81M-NEXT: mov r0, sp
330 ; CHECK-81M-NEXT: bl func51
331 ; CHECK-81M-NEXT: sub.w r4, r7, #8
332 ; CHECK-81M-NEXT: mov sp, r4
333 ; CHECK-81M-NEXT: pop.w {r4, r6, r7, lr}
334 ; CHECK-81M-NEXT: vscclrm {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, vpr}
335 ; CHECK-81M-NEXT: vldr fpcxtns, [sp], #4
336 ; CHECK-81M-NEXT: clrm {r0, r1, r2, r3, r12, apsr}
337 ; CHECK-81M-NEXT: bxns lr
338 %1 = alloca i8, align 16
339 call void @func51(i8* nonnull %1) #5
344 attributes #4 = { "cmse_nonsecure_entry" nounwind }
345 attributes #5 = { nounwind }