Reapply "blockfreq: Rewrite BlockFrequencyInfoImpl"
[oota-llvm.git] / test / CodeGen / XCore / llvm-intrinsics.ll
1 ; RUN: llc < %s -march=xcore | FileCheck %s
2 ; RUN: llc < %s -march=xcore -disable-fp-elim | FileCheck %s -check-prefix=CHECKFP
3
4 declare i8* @llvm.frameaddress(i32) nounwind readnone
5 declare i8* @llvm.returnaddress(i32) nounwind
6 declare i8* @llvm.eh.dwarf.cfa(i32) nounwind
7 declare void @llvm.eh.return.i32(i32, i8*) nounwind
8 declare void @llvm.eh.unwind.init() nounwind
9
10 define i8* @FA0() nounwind {
11 entry:
12 ; CHECK-LABEL: FA0
13 ; CHECK: ldaw r0, sp[0]
14 ; CHECK-NEXT: retsp 0
15   %0 = call i8* @llvm.frameaddress(i32 0)
16   ret i8* %0
17 }
18
19 define i8* @FA1() nounwind {
20 entry:
21 ; CHECK-LABEL: FA1
22 ; CHECK: entsp 100
23 ; CHECK-NEXT: ldaw r0, sp[0]
24 ; CHECK-NEXT: retsp 100
25   %0 = alloca [100 x i32]
26   %1 = call i8* @llvm.frameaddress(i32 0)
27   ret i8* %1
28 }
29
30 define i8* @RA0() nounwind {
31 entry:
32 ; CHECK-LABEL: RA0
33 ; CHECK: stw lr, sp[0]
34 ; CHECK-NEXT: ldw r0, sp[0]
35 ; CHECK-NEXT: ldw lr, sp[0]
36 ; CHECK-NEXT: retsp 0
37   %0 = call i8* @llvm.returnaddress(i32 0)
38   ret i8* %0
39 }
40
41 define i8* @RA1() nounwind {
42 entry:
43 ; CHECK-LABEL: RA1
44 ; CHECK: entsp 100
45 ; CHECK-NEXT: ldw r0, sp[100]
46 ; CHECK-NEXT: retsp 100
47   %0 = alloca [100 x i32]
48   %1 = call i8* @llvm.returnaddress(i32 0)
49   ret i8* %1
50 }
51
52 ; test FRAME_TO_ARGS_OFFSET lowering
53 define i8* @FTAO0() nounwind {
54 entry:
55 ; CHECK-LABEL: FTAO0
56 ; CHECK: ldc r0, 0
57 ; CHECK-NEXT: ldaw r1, sp[0]
58 ; CHECK-NEXT: add r0, r1, r0
59 ; CHECK-NEXT: retsp 0
60   %0 = call i8* @llvm.eh.dwarf.cfa(i32 0)
61   ret i8* %0
62 }
63
64 define i8* @FTAO1() nounwind {
65 entry:
66 ; CHECK-LABEL: FTAO1
67 ; CHECK: entsp 100
68 ; CHECK-NEXT: ldc r0, 400
69 ; CHECK-NEXT: ldaw r1, sp[0]
70 ; CHECK-NEXT: add r0, r1, r0
71 ; CHECK-NEXT: retsp 100
72   %0 = alloca [100 x i32]
73   %1 = call i8* @llvm.eh.dwarf.cfa(i32 0)
74   ret i8* %1
75 }
76
77 define i8* @EH0(i32 %offset, i8* %handler) {
78 entry:
79 ; CHECK-LABEL: EH0
80 ; CHECK: entsp 2
81 ; CHECK: .cfi_def_cfa_offset 8
82 ; CHECK: .cfi_offset 15, 0
83 ; CHECK: .cfi_offset 1, -8
84 ; CHECK: .cfi_offset 0, -4
85 ; CHECK: ldc r2, 8
86 ; CHECK-NEXT: ldaw r3, sp[0]
87 ; CHECK-NEXT: add r2, r3, r2
88 ; CHECK-NEXT: add r2, r2, r0
89 ; CHECK-NEXT: mov r3, r1
90 ; CHECK-NEXT: ldw r1, sp[0]
91 ; CHECK-NEXT: ldw r0, sp[1]
92 ; CHECK-NEXT: set sp, r2
93 ; CHECK-NEXT: bau r3
94   call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
95   unreachable
96 }
97
98 declare void @foo(...)
99 define i8* @EH1(i32 %offset, i8* %handler) {
100 entry:
101 ; CHECK-LABEL: EH1
102 ; CHECK: entsp 5
103 ; CHECK: .cfi_def_cfa_offset 20
104 ; CHECK: .cfi_offset 15, 0
105 ; CHECK: .cfi_offset 1, -16
106 ; CHECK: .cfi_offset 0, -12
107 ; CHECK: stw r4, sp[4]
108 ; CHECK: .cfi_offset 4, -4
109 ; CHECK: stw r5, sp[3]
110 ; CHECK: .cfi_offset 5, -8
111 ; CHECK: mov r4, r1
112 ; CHECK-NEXT: mov r5, r0
113 ; CHECK-NEXT: bl foo
114 ; CHECK-NEXT: ldc r0, 20
115 ; CHECK-NEXT: ldaw r1, sp[0]
116 ; CHECK-NEXT: add r0, r1, r0
117 ; CHECK-NEXT: add r2, r0, r5
118 ; CHECK-NEXT: mov r3, r4
119 ; CHECK-NEXT: ldw r5, sp[3]
120 ; CHECK-NEXT: ldw r4, sp[4]
121 ; CHECK-NEXT: ldw r1, sp[1]
122 ; CHECK-NEXT: ldw r0, sp[2]
123 ; CHECK-NEXT: set sp, r2
124 ; CHECK-NEXT: bau r3
125   call void (...)* @foo()
126   call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
127   unreachable
128 }
129
130 @offset = external constant i32
131 @handler = external constant i8
132 define i8* @EH2(i32 %r0, i32 %r1, i32 %r2, i32 %r3) {
133 entry:
134 ; CHECK-LABEL: EH2
135 ; CHECK: entsp 3
136 ; CHECK: bl foo
137 ; CHECK-NEXT: ldw r0, dp[offset]
138 ; CHECK-NEXT: ldc r1, 12
139 ; CHECK-NEXT: ldaw r2, sp[0]
140 ; CHECK-NEXT: add r1, r2, r1
141 ; CHECK-NEXT: add r2, r1, r0
142 ; CHECK-NEXT: ldaw r3, dp[handler]
143 ; CHECK-NEXT: ldw r1, sp[1]
144 ; CHECK-NEXT: ldw r0, sp[2]
145 ; CHECK-NEXT: set sp, r2
146 ; CHECK-NEXT: bau r3
147   call void (...)* @foo()
148   %0 = load i32* @offset
149   call void @llvm.eh.return.i32(i32 %0, i8* @handler)
150   unreachable
151 }
152
153
154 ; FP: spill FP+SR+R0:1+R4:9 = entsp 2+2+6
155 ; But we dont actually spill or restore R0:1
156 ; CHECKFP-LABEL: Unwind0:
157 ; CHECKFP: entsp 10
158 ; CHECKFP: stw r10, sp[1]
159 ; CHECKFP: ldaw r10, sp[0]
160 ; CHECKFP: stw r4, r10[9]
161 ; CHECKFP: stw r5, r10[8]
162 ; CHECKFP: stw r6, r10[7]
163 ; CHECKFP: stw r7, r10[6]
164 ; CHECKFP: stw r8, r10[5]
165 ; CHECKFP: stw r9, r10[4]
166 ; CHECKFP: ldw r9, r10[4]
167 ; CHECKFP: ldw r8, r10[5]
168 ; CHECKFP: ldw r7, r10[6]
169 ; CHECKFP: ldw r6, r10[7]
170 ; CHECKFP: ldw r5, r10[8]
171 ; CHECKFP: ldw r4, r10[9]
172 ; CHECKFP: set sp, r10
173 ; CHECKFP: ldw r10, sp[1]
174 ; CHECKFP: retsp 10
175 ;
176 ; !FP: spill R0:1+R4:10 = entsp 2+7
177 ; But we dont actually spill or restore R0:1
178 ; CHECK-LABEL: Unwind0:
179 ; CHECK: entsp 9
180 ; CHECK: stw r4, sp[8]
181 ; CHECK: stw r5, sp[7]
182 ; CHECK: stw r6, sp[6]
183 ; CHECK: stw r7, sp[5]
184 ; CHECK: stw r8, sp[4]
185 ; CHECK: stw r9, sp[3]
186 ; CHECK: stw r10, sp[2]
187 ; CHECK: ldw r10, sp[2]
188 ; CHECK: ldw r9, sp[3]
189 ; CHECK: ldw r8, sp[4]
190 ; CHECK: ldw r7, sp[5]
191 ; CHECK: ldw r6, sp[6]
192 ; CHECK: ldw r5, sp[7]
193 ; CHECK: ldw r4, sp[8]
194 ; CHECK: retsp 9
195 define void @Unwind0() {
196   call void @llvm.eh.unwind.init()
197   ret void
198 }
199
200
201 ; FP: spill FP+SR+R0:1+R4:9+LR = entsp 2+2+6 + extsp 1
202 ; But we dont actually spill or restore R0:1
203 ; CHECKFP-LABEL: Unwind1:
204 ; CHECKFP: entsp 10
205 ; CHECKFP: stw r10, sp[1]
206 ; CHECKFP: ldaw r10, sp[0]
207 ; CHECKFP: stw r4, r10[9]
208 ; CHECKFP: stw r5, r10[8]
209 ; CHECKFP: stw r6, r10[7]
210 ; CHECKFP: stw r7, r10[6]
211 ; CHECKFP: stw r8, r10[5]
212 ; CHECKFP: stw r9, r10[4]
213 ; CHECKFP: extsp 1
214 ; CHECKFP: bl foo
215 ; CHECKFP: ldaw sp, sp[1]
216 ; CHECKFP: ldw r9, r10[4]
217 ; CHECKFP: ldw r8, r10[5]
218 ; CHECKFP: ldw r7, r10[6]
219 ; CHECKFP: ldw r6, r10[7]
220 ; CHECKFP: ldw r5, r10[8]
221 ; CHECKFP: ldw r4, r10[9]
222 ; CHECKFP: set sp, r10
223 ; CHECKFP: ldw r10, sp[1]
224 ; CHECKFP: retsp 10
225 ;
226 ; !FP: spill R0:1+R4:10+LR = entsp 2+7+1
227 ; But we dont actually spill or restore R0:1
228 ; CHECK-LABEL: Unwind1:
229 ; CHECK: entsp 10
230 ; CHECK: stw r4, sp[9]
231 ; CHECK: stw r5, sp[8]
232 ; CHECK: stw r6, sp[7]
233 ; CHECK: stw r7, sp[6]
234 ; CHECK: stw r8, sp[5]
235 ; CHECK: stw r9, sp[4]
236 ; CHECK: stw r10, sp[3]
237 ; CHECK: bl foo
238 ; CHECK: ldw r10, sp[3]
239 ; CHECK: ldw r9, sp[4]
240 ; CHECK: ldw r8, sp[5]
241 ; CHECK: ldw r7, sp[6]
242 ; CHECK: ldw r6, sp[7]
243 ; CHECK: ldw r5, sp[8]
244 ; CHECK: ldw r4, sp[9]
245 ; CHECK: retsp 10
246 define void @Unwind1() {
247   call void (...)* @foo()
248   call void @llvm.eh.unwind.init()
249   ret void
250 }
251
252 ; FP: spill FP+SR+R0:1+R4:9 = entsp 2+2+6
253 ; We dont spill R0:1
254 ; We only restore R0:1 during eh.return
255 ; CHECKFP-LABEL: UnwindEH:
256 ; CHECKFP: entsp 10
257 ; CHECKFP: .cfi_def_cfa_offset 40
258 ; CHECKFP: .cfi_offset 15, 0
259 ; CHECKFP: stw r10, sp[1]
260 ; CHECKFP: .cfi_offset 10, -36
261 ; CHECKFP: ldaw r10, sp[0]
262 ; CHECKFP: .cfi_def_cfa_register 10
263 ; CHECKFP: .cfi_offset 1, -32
264 ; CHECKFP: .cfi_offset 0, -28
265 ; CHECKFP: stw r4, r10[9]
266 ; CHECKFP: .cfi_offset 4, -4
267 ; CHECKFP: stw r5, r10[8]
268 ; CHECKFP: .cfi_offset 5, -8
269 ; CHECKFP: stw r6, r10[7]
270 ; CHECKFP: .cfi_offset 6, -12
271 ; CHECKFP: stw r7, r10[6]
272 ; CHECKFP: .cfi_offset 7, -16
273 ; CHECKFP: stw r8, r10[5]
274 ; CHECKFP: .cfi_offset 8, -20
275 ; CHECKFP: stw r9, r10[4]
276 ; CHECKFP: .cfi_offset 9, -24
277 ; CHECKFP: bt r0, .LBB{{[0-9_]+}}
278 ; CHECKFP: ldw r9, r10[4]
279 ; CHECKFP-NEXT: ldw r8, r10[5]
280 ; CHECKFP-NEXT: ldw r7, r10[6]
281 ; CHECKFP-NEXT: ldw r6, r10[7]
282 ; CHECKFP-NEXT: ldw r5, r10[8]
283 ; CHECKFP-NEXT: ldw r4, r10[9]
284 ; CHECKFP-NEXT: set sp, r10
285 ; CHECKFP-NEXT: ldw r10, sp[1]
286 ; CHECKFP-NEXT: retsp 10
287 ; CHECKFP: .LBB{{[0-9_]+}}
288 ; CHECKFP-NEXT: ldc r2, 40
289 ; CHECKFP-NEXT: add r2, r10, r2
290 ; CHECKFP-NEXT: add r2, r2, r0
291 ; CHECKFP-NEXT: mov r3, r1
292 ; CHECKFP-NEXT: ldw r9, r10[4]
293 ; CHECKFP-NEXT: ldw r8, r10[5]
294 ; CHECKFP-NEXT: ldw r7, r10[6]
295 ; CHECKFP-NEXT: ldw r6, r10[7]
296 ; CHECKFP-NEXT: ldw r5, r10[8]
297 ; CHECKFP-NEXT: ldw r4, r10[9]
298 ; CHECKFP-NEXT: ldw r1, sp[2]
299 ; CHECKFP-NEXT: ldw r0, sp[3]
300 ; CHECKFP-NEXT: set sp, r2
301 ; CHECKFP-NEXT: bau r3
302 ;
303 ; !FP: spill R0:1+R4:10 = entsp 2+7
304 ; We dont spill R0:1
305 ; We only restore R0:1 during eh.return
306 ; CHECK-LABEL: UnwindEH:
307 ; CHECK: entsp 9
308 ; CHECK: .cfi_def_cfa_offset 36
309 ; CHECK: .cfi_offset 15, 0
310 ; CHECK: .cfi_offset 1, -36
311 ; CHECK: .cfi_offset 0, -32
312 ; CHECK: stw r4, sp[8]
313 ; CHECK: .cfi_offset 4, -4
314 ; CHECK: stw r5, sp[7]
315 ; CHECK: .cfi_offset 5, -8
316 ; CHECK: stw r6, sp[6]
317 ; CHECK: .cfi_offset 6, -12
318 ; CHECK: stw r7, sp[5]
319 ; CHECK: .cfi_offset 7, -16
320 ; CHECK: stw r8, sp[4]
321 ; CHECK: .cfi_offset 8, -20
322 ; CHECK: stw r9, sp[3]
323 ; CHECK: .cfi_offset 9, -24
324 ; CHECK: stw r10, sp[2]
325 ; CHECK: .cfi_offset 10, -28
326 ; CHECK: bt r0, .LBB{{[0-9_]+}}
327 ; CHECK: ldw r10, sp[2]
328 ; CHECK-NEXT: ldw r9, sp[3]
329 ; CHECK-NEXT: ldw r8, sp[4]
330 ; CHECK-NEXT: ldw r7, sp[5]
331 ; CHECK-NEXT: ldw r6, sp[6]
332 ; CHECK-NEXT: ldw r5, sp[7]
333 ; CHECK-NEXT: ldw r4, sp[8]
334 ; CHECK-NEXT: retsp 9
335 ; CHECK: .LBB{{[0-9_]+}}
336 ; CHECK-NEXT: ldc r2, 36
337 ; CHECK-NEXT: ldaw r3, sp[0]
338 ; CHECK-NEXT: add r2, r3, r2
339 ; CHECK-NEXT: add r2, r2, r0
340 ; CHECK-NEXT: mov r3, r1
341 ; CHECK-NEXT: ldw r10, sp[2]
342 ; CHECK-NEXT: ldw r9, sp[3]
343 ; CHECK-NEXT: ldw r8, sp[4]
344 ; CHECK-NEXT: ldw r7, sp[5]
345 ; CHECK-NEXT: ldw r6, sp[6]
346 ; CHECK-NEXT: ldw r5, sp[7]
347 ; CHECK-NEXT: ldw r4, sp[8]
348 ; CHECK-NEXT: ldw r1, sp[0]
349 ; CHECK-NEXT: ldw r0, sp[1]
350 ; CHECK-NEXT: set sp, r2
351 ; CHECK-NEXT: bau r3
352 define void @UnwindEH(i32 %offset, i8* %handler) {
353   call void @llvm.eh.unwind.init()
354   %cmp = icmp eq i32 %offset, 0
355   br i1 %cmp, label %normal, label %eh
356 eh:
357   call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
358   unreachable
359 normal:
360   ret void
361 }