xref: /llvm-project/llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs.ll (revision 3abf55a68caefd45042c27b73a658c638afbbb8b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2; RUN: opt < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+sme -S -passes=inline | FileCheck %s
3
4declare i32 @llvm.vscale.i32()
5
6; Define some functions that merely call llvm.vscale.i32(), which will be called
7; by the other functions below. If we see the call to one of these functions
8; being replaced by 'llvm.vscale()', then we know it has been inlined.
9
10define i32 @normal_callee() {
11; CHECK-LABEL: define i32 @normal_callee
12; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.vscale.i32()
15; CHECK-NEXT:    ret i32 [[RES]]
16;
17entry:
18  %res = call i32 @llvm.vscale.i32()
19  ret i32 %res
20}
21
22define i32 @streaming_callee() "aarch64_pstate_sm_enabled" {
23; CHECK-LABEL: define i32 @streaming_callee
24; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
25; CHECK-NEXT:  entry:
26; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.vscale.i32()
27; CHECK-NEXT:    ret i32 [[RES]]
28;
29entry:
30  %res = call i32 @llvm.vscale.i32()
31  ret i32 %res
32}
33
34define i32 @locally_streaming_callee() "aarch64_pstate_sm_body" {
35; CHECK-LABEL: define i32 @locally_streaming_callee
36; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
37; CHECK-NEXT:  entry:
38; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.vscale.i32()
39; CHECK-NEXT:    ret i32 [[RES]]
40;
41entry:
42  %res = call i32 @llvm.vscale.i32()
43  ret i32 %res
44}
45
46define i32 @streaming_compatible_callee() "aarch64_pstate_sm_compatible" {
47; CHECK-LABEL: define i32 @streaming_compatible_callee
48; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
49; CHECK-NEXT:  entry:
50; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.vscale.i32()
51; CHECK-NEXT:    ret i32 [[RES]]
52;
53entry:
54  %res = call i32 @llvm.vscale.i32()
55  ret i32 %res
56}
57
58define i32 @streaming_compatible_locally_streaming_callee() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" {
59; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_callee
60; CHECK-SAME: () #[[ATTR4:[0-9]+]] {
61; CHECK-NEXT:  entry:
62; CHECK-NEXT:    [[RES:%.*]] = call i32 @llvm.vscale.i32()
63; CHECK-NEXT:    ret i32 [[RES]]
64;
65entry:
66  %res = call i32 @llvm.vscale()
67  ret i32 %res
68}
69
70; Now test that inlining only happens when their streaming modes match.
71; Test for a number of combinations, where:
72; N       Normal-interface (PSTATE.SM=0 on entry/exit)
73; S       Streaming-interface (PSTATE.SM=1 on entry/exit)
74; SC      Streaming-compatible interface
75;         (PSTATE.SM=0 or 1, unchanged on exit)
76; N + B   Normal-interface, streaming body
77;         (PSTATE.SM=0 on entry/exit, but 1 within the body of the function)
78; SC + B  Streaming-compatible-interface, streaming body
79;         (PSTATE.SM=0 or 1 on entry, unchanged on exit,
80;          but guaranteed to be 1 within the body of the function)
81
82; [x] N  -> N
83; [ ] N  -> S
84; [ ] N  -> SC
85; [ ] N  -> N + B
86; [ ] N  -> SC + B
87define i32 @normal_caller_normal_callee_inline() {
88; CHECK-LABEL: define i32 @normal_caller_normal_callee_inline
89; CHECK-SAME: () #[[ATTR1]] {
90; CHECK-NEXT:  entry:
91; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
92; CHECK-NEXT:    ret i32 [[RES_I]]
93;
94entry:
95  %res = call i32 @normal_callee()
96  ret i32 %res
97}
98
99; [ ] N  -> N
100; [x] N  -> S
101; [ ] N  -> SC
102; [ ] N  -> N + B
103; [ ] N  -> SC + B
104define i32 @normal_caller_streaming_callee_dont_inline() {
105; CHECK-LABEL: define i32 @normal_caller_streaming_callee_dont_inline
106; CHECK-SAME: () #[[ATTR1]] {
107; CHECK-NEXT:  entry:
108; CHECK-NEXT:    [[RES:%.*]] = call i32 @streaming_callee()
109; CHECK-NEXT:    ret i32 [[RES]]
110;
111entry:
112  %res = call i32 @streaming_callee()
113  ret i32 %res
114}
115
116; [ ] N  -> N
117; [ ] N  -> S
118; [x] N  -> SC
119; [ ] N  -> N + B
120; [ ] N  -> SC + B
121define i32 @normal_caller_streaming_compatible_callee_inline() {
122; CHECK-LABEL: define i32 @normal_caller_streaming_compatible_callee_inline
123; CHECK-SAME: () #[[ATTR1]] {
124; CHECK-NEXT:  entry:
125; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
126; CHECK-NEXT:    ret i32 [[RES_I]]
127;
128entry:
129  %res = call i32 @streaming_compatible_callee()
130  ret i32 %res
131}
132
133; [ ] N  -> N
134; [ ] N  -> S
135; [ ] N  -> SC
136; [x] N  -> N + B
137; [ ] N  -> SC + B
138define i32 @normal_caller_locally_streaming_callee_dont_inline() {
139; CHECK-LABEL: define i32 @normal_caller_locally_streaming_callee_dont_inline
140; CHECK-SAME: () #[[ATTR1]] {
141; CHECK-NEXT:  entry:
142; CHECK-NEXT:    [[RES:%.*]] = call i32 @locally_streaming_callee()
143; CHECK-NEXT:    ret i32 [[RES]]
144;
145entry:
146  %res = call i32 @locally_streaming_callee()
147  ret i32 %res
148}
149
150; [ ] N  -> N
151; [ ] N  -> S
152; [ ] N  -> SC
153; [ ] N  -> N + B
154; [x] N  -> SC + B
155define i32 @normal_caller_streaming_compatible_locally_streaming_callee_dont_inline() {
156; CHECK-LABEL: define i32 @normal_caller_streaming_compatible_locally_streaming_callee_dont_inline
157; CHECK-SAME: () #[[ATTR1]] {
158; CHECK-NEXT:  entry:
159; CHECK-NEXT:    [[RES:%.*]] = call i32 @streaming_compatible_locally_streaming_callee()
160; CHECK-NEXT:    ret i32 [[RES]]
161;
162entry:
163  %res = call i32 @streaming_compatible_locally_streaming_callee()
164  ret i32 %res
165}
166
167; [x] S  -> N
168; [ ] S  -> S
169; [ ] S  -> SC
170; [ ] S  -> N + B
171; [ ] S  -> SC + B
172define i32 @streaming_caller_normal_callee_dont_inline() "aarch64_pstate_sm_enabled" {
173; CHECK-LABEL: define i32 @streaming_caller_normal_callee_dont_inline
174; CHECK-SAME: () #[[ATTR2]] {
175; CHECK-NEXT:  entry:
176; CHECK-NEXT:    [[RES:%.*]] = call i32 @normal_callee()
177; CHECK-NEXT:    ret i32 [[RES]]
178;
179entry:
180  %res = call i32 @normal_callee()
181  ret i32 %res
182}
183
184; [ ] S  -> N
185; [x] S  -> S
186; [ ] S  -> SC
187; [ ] S  -> N + B
188; [ ] S  -> SC + B
189define i32 @streaming_caller_streaming_callee_inline() "aarch64_pstate_sm_enabled" {
190; CHECK-LABEL: define i32 @streaming_caller_streaming_callee_inline
191; CHECK-SAME: () #[[ATTR2]] {
192; CHECK-NEXT:  entry:
193; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
194; CHECK-NEXT:    ret i32 [[RES_I]]
195;
196entry:
197  %res = call i32 @streaming_callee()
198  ret i32 %res
199}
200
201; [ ] S  -> N
202; [ ] S  -> S
203; [x] S  -> SC
204; [ ] S  -> N + B
205; [ ] S  -> SC + B
206define i32 @streaming_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_enabled" {
207; CHECK-LABEL: define i32 @streaming_caller_streaming_compatible_callee_inline
208; CHECK-SAME: () #[[ATTR2]] {
209; CHECK-NEXT:  entry:
210; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
211; CHECK-NEXT:    ret i32 [[RES_I]]
212;
213entry:
214  %res = call i32 @streaming_compatible_callee()
215  ret i32 %res
216}
217
218; [ ] S  -> N
219; [ ] S  -> S
220; [ ] S  -> SC
221; [x] S  -> N + B
222; [ ] S  -> SC + B
223define i32 @streaming_caller_locally_streaming_callee_inline() "aarch64_pstate_sm_enabled" {
224; CHECK-LABEL: define i32 @streaming_caller_locally_streaming_callee_inline
225; CHECK-SAME: () #[[ATTR2]] {
226; CHECK-NEXT:  entry:
227; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
228; CHECK-NEXT:    ret i32 [[RES_I]]
229;
230entry:
231  %res = call i32 @locally_streaming_callee()
232  ret i32 %res
233}
234
235; [ ] S  -> N
236; [ ] S  -> S
237; [ ] S  -> SC
238; [ ] S  -> N + B
239; [x] S  -> SC + B
240define i32 @streaming_caller_streaming_compatible_locally_streaming_callee_inline() "aarch64_pstate_sm_enabled" {
241; CHECK-LABEL: define i32 @streaming_caller_streaming_compatible_locally_streaming_callee_inline
242; CHECK-SAME: () #[[ATTR2]] {
243; CHECK-NEXT:  entry:
244; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
245; CHECK-NEXT:    ret i32 [[RES_I]]
246;
247entry:
248  %res = call i32 @streaming_compatible_locally_streaming_callee()
249  ret i32 %res
250}
251
252; [x] N + B -> N
253; [ ] N + B -> S
254; [ ] N + B -> SC
255; [ ] N + B -> N + B
256; [ ] N + B -> SC + B
257define i32 @locally_streaming_caller_normal_callee_dont_inline() "aarch64_pstate_sm_body" {
258; CHECK-LABEL: define i32 @locally_streaming_caller_normal_callee_dont_inline
259; CHECK-SAME: () #[[ATTR3]] {
260; CHECK-NEXT:  entry:
261; CHECK-NEXT:    [[RES:%.*]] = call i32 @normal_callee()
262; CHECK-NEXT:    ret i32 [[RES]]
263;
264entry:
265  %res = call i32 @normal_callee()
266  ret i32 %res
267}
268
269; [ ] N + B -> N
270; [x] N + B -> S
271; [ ] N + B -> SC
272; [ ] N + B -> N + B
273; [ ] N + B -> SC + B
274define i32 @locally_streaming_caller_streaming_callee_inline() "aarch64_pstate_sm_body" {
275; CHECK-LABEL: define i32 @locally_streaming_caller_streaming_callee_inline
276; CHECK-SAME: () #[[ATTR3]] {
277; CHECK-NEXT:  entry:
278; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
279; CHECK-NEXT:    ret i32 [[RES_I]]
280;
281entry:
282  %res = call i32 @streaming_callee()
283  ret i32 %res
284}
285
286; [ ] N + B -> N
287; [ ] N + B -> S
288; [x] N + B -> SC
289; [ ] N + B -> N + B
290; [ ] N + B -> SC + B
291define i32 @locally_streaming_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_body" {
292; CHECK-LABEL: define i32 @locally_streaming_caller_streaming_compatible_callee_inline
293; CHECK-SAME: () #[[ATTR3]] {
294; CHECK-NEXT:  entry:
295; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
296; CHECK-NEXT:    ret i32 [[RES_I]]
297;
298entry:
299  %res = call i32 @streaming_compatible_callee()
300  ret i32 %res
301}
302
303; [ ] N + B -> N
304; [ ] N + B -> S
305; [ ] N + B -> SC
306; [x] N + B -> N + B
307; [ ] N + B -> SC + B
308define i32 @locally_streaming_caller_locally_streaming_callee_inline() "aarch64_pstate_sm_body" {
309; CHECK-LABEL: define i32 @locally_streaming_caller_locally_streaming_callee_inline
310; CHECK-SAME: () #[[ATTR3]] {
311; CHECK-NEXT:  entry:
312; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
313; CHECK-NEXT:    ret i32 [[RES_I]]
314;
315entry:
316  %res = call i32 @locally_streaming_callee()
317  ret i32 %res
318}
319
320; [ ] N + B -> N
321; [ ] N + B -> S
322; [ ] N + B -> SC
323; [ ] N + B -> N + B
324; [x] N + B -> SC + B
325define i32 @locally_streaming_caller_streaming_compatible_locally_streaming_callee_inline() "aarch64_pstate_sm_body" {
326; CHECK-LABEL: define i32 @locally_streaming_caller_streaming_compatible_locally_streaming_callee_inline
327; CHECK-SAME: () #[[ATTR3]] {
328; CHECK-NEXT:  entry:
329; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
330; CHECK-NEXT:    ret i32 [[RES_I]]
331;
332entry:
333  %res = call i32 @streaming_compatible_locally_streaming_callee()
334  ret i32 %res
335}
336
337; [x] SC -> N
338; [ ] SC -> S
339; [ ] SC -> SC
340; [ ] SC -> N + B
341; [ ] SC -> SC + B
342define i32 @streaming_compatible_caller_normal_callee_dont_inline() "aarch64_pstate_sm_compatible" {
343; CHECK-LABEL: define i32 @streaming_compatible_caller_normal_callee_dont_inline
344; CHECK-SAME: () #[[ATTR0]] {
345; CHECK-NEXT:  entry:
346; CHECK-NEXT:    [[RES:%.*]] = call i32 @normal_callee()
347; CHECK-NEXT:    ret i32 [[RES]]
348;
349entry:
350  %res = call i32 @normal_callee()
351  ret i32 %res
352}
353
354; [ ] SC -> N
355; [x] SC -> S
356; [ ] SC -> SC
357; [ ] SC -> N + B
358; [ ] SC -> SC + B
359define i32 @streaming_compatible_caller_streaming_callee_dont_inline() "aarch64_pstate_sm_compatible" {
360; CHECK-LABEL: define i32 @streaming_compatible_caller_streaming_callee_dont_inline
361; CHECK-SAME: () #[[ATTR0]] {
362; CHECK-NEXT:  entry:
363; CHECK-NEXT:    [[RES:%.*]] = call i32 @streaming_callee()
364; CHECK-NEXT:    ret i32 [[RES]]
365;
366entry:
367  %res = call i32 @streaming_callee()
368  ret i32 %res
369}
370
371; [ ] SC -> N
372; [ ] SC -> S
373; [x] SC -> SC
374; [ ] SC -> N + B
375; [ ] SC -> SC + B
376define i32 @streaming_compatible_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_compatible" {
377; CHECK-LABEL: define i32 @streaming_compatible_caller_streaming_compatible_callee_inline
378; CHECK-SAME: () #[[ATTR0]] {
379; CHECK-NEXT:  entry:
380; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
381; CHECK-NEXT:    ret i32 [[RES_I]]
382;
383entry:
384  %res = call i32 @streaming_compatible_callee()
385  ret i32 %res
386}
387
388; [ ] SC -> N
389; [ ] SC -> S
390; [ ] SC -> SC
391; [x] SC -> N + B
392; [ ] SC -> SC + B
393define i32 @streaming_compatible_caller_locally_streaming_callee_dont_inline() "aarch64_pstate_sm_compatible" {
394; CHECK-LABEL: define i32 @streaming_compatible_caller_locally_streaming_callee_dont_inline
395; CHECK-SAME: () #[[ATTR0]] {
396; CHECK-NEXT:  entry:
397; CHECK-NEXT:    [[RES:%.*]] = call i32 @locally_streaming_callee()
398; CHECK-NEXT:    ret i32 [[RES]]
399;
400entry:
401  %res = call i32 @locally_streaming_callee()
402  ret i32 %res
403}
404
405; [ ] SC -> N
406; [ ] SC -> S
407; [ ] SC -> SC
408; [ ] SC -> N + B
409; [x] SC -> SC + B
410define i32 @streaming_compatible_caller_streaming_compatible_locally_streaming_callee_dont_inline() "aarch64_pstate_sm_compatible" {
411; CHECK-LABEL: define i32 @streaming_compatible_caller_streaming_compatible_locally_streaming_callee_dont_inline
412; CHECK-SAME: () #[[ATTR0]] {
413; CHECK-NEXT:  entry:
414; CHECK-NEXT:    [[RES:%.*]] = call i32 @streaming_compatible_locally_streaming_callee()
415; CHECK-NEXT:    ret i32 [[RES]]
416;
417entry:
418  %res = call i32 @streaming_compatible_locally_streaming_callee()
419  ret i32 %res
420}
421; [x] SC + B -> N
422; [ ] SC + B -> S
423; [ ] SC + B -> SC
424; [ ] SC + B -> N + B
425; [ ] SC + B -> SC + B
426define i32 @streaming_compatible_locally_streaming_caller_normal_callee_dont_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" {
427; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_normal_callee_dont_inline
428; CHECK-SAME: () #[[ATTR4]] {
429; CHECK-NEXT:  entry:
430; CHECK-NEXT:    [[RES:%.*]] = call i32 @normal_callee()
431; CHECK-NEXT:    ret i32 [[RES]]
432;
433entry:
434  %res = call i32 @normal_callee()
435  ret i32 %res
436}
437
438; [ ] SC + B -> N
439; [x] SC + B -> S
440; [ ] SC + B -> SC
441; [ ] SC + B -> N + B
442; [ ] SC + B -> SC + B
443define i32 @streaming_compatible_locally_streaming_caller_streaming_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" {
444; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_streaming_callee_inline
445; CHECK-SAME: () #[[ATTR4]] {
446; CHECK-NEXT:  entry:
447; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
448; CHECK-NEXT:    ret i32 [[RES_I]]
449;
450entry:
451  %res = call i32 @streaming_callee()
452  ret i32 %res
453}
454
455; [ ] SC + B -> N
456; [ ] SC + B -> S
457; [x] SC + B -> SC
458; [ ] SC + B -> N + B
459; [ ] SC + B -> SC + B
460define i32 @streaming_compatible_locally_streaming_caller_streaming_compatible_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" {
461; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_streaming_compatible_callee_inline
462; CHECK-SAME: () #[[ATTR4]] {
463; CHECK-NEXT:  entry:
464; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
465; CHECK-NEXT:    ret i32 [[RES_I]]
466;
467entry:
468  %res = call i32 @streaming_compatible_callee()
469  ret i32 %res
470}
471
472; [ ] SC + B -> N
473; [ ] SC + B -> S
474; [ ] SC + B -> SC
475; [x] SC + B -> N + B
476; [ ] SC + B -> SC + B
477define i32 @streaming_compatible_locally_streaming_caller_locally_streaming_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" {
478; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_locally_streaming_callee_inline
479; CHECK-SAME: () #[[ATTR4]] {
480; CHECK-NEXT:  entry:
481; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
482; CHECK-NEXT:    ret i32 [[RES_I]]
483;
484entry:
485  %res = call i32 @locally_streaming_callee()
486  ret i32 %res
487}
488
489; [ ] SC + B -> N
490; [ ] SC + B -> S
491; [ ] SC + B -> SC
492; [ ] SC + B -> N + B
493; [x] SC + B -> SC + B
494define i32 @streaming_compatible_locally_streaming_caller_and_callee_inline() "aarch64_pstate_sm_compatible" "aarch64_pstate_sm_body" {
495; CHECK-LABEL: define i32 @streaming_compatible_locally_streaming_caller_and_callee_inline
496; CHECK-SAME: () #[[ATTR4]] {
497; CHECK-NEXT:  entry:
498; CHECK-NEXT:    [[RES_I:%.*]] = call i32 @llvm.vscale.i32()
499; CHECK-NEXT:    ret i32 [[RES_I]]
500;
501entry:
502  %res = call i32 @streaming_compatible_locally_streaming_callee()
503  ret i32 %res
504}
505
506define void @normal_callee_with_inlineasm() {
507; CHECK-LABEL: define void @normal_callee_with_inlineasm
508; CHECK-SAME: () #[[ATTR1]] {
509; CHECK-NEXT:  entry:
510; CHECK-NEXT:    call void asm sideeffect "
511; CHECK-NEXT:    ret void
512;
513entry:
514  call void asm sideeffect "; inlineasm", ""()
515  ret void
516}
517
518define void @streaming_caller_normal_callee_with_inlineasm_dont_inline() "aarch64_pstate_sm_enabled" {
519; CHECK-LABEL: define void @streaming_caller_normal_callee_with_inlineasm_dont_inline
520; CHECK-SAME: () #[[ATTR2]] {
521; CHECK-NEXT:  entry:
522; CHECK-NEXT:    call void @normal_callee_with_inlineasm()
523; CHECK-NEXT:    ret void
524;
525entry:
526  call void @normal_callee_with_inlineasm()
527  ret void
528}
529
530define i64 @normal_callee_with_intrinsic_call() {
531; CHECK-LABEL: define i64 @normal_callee_with_intrinsic_call
532; CHECK-SAME: () #[[ATTR1]] {
533; CHECK-NEXT:  entry:
534; CHECK-NEXT:    [[RES:%.*]] = call i64 @llvm.aarch64.sve.cntb(i32 4)
535; CHECK-NEXT:    ret i64 [[RES]]
536;
537entry:
538  %res = call i64 @llvm.aarch64.sve.cntb(i32 4)
539  ret i64 %res
540}
541
542define i64 @streaming_caller_normal_callee_with_intrinsic_call_dont_inline() "aarch64_pstate_sm_enabled" {
543; CHECK-LABEL: define i64 @streaming_caller_normal_callee_with_intrinsic_call_dont_inline
544; CHECK-SAME: () #[[ATTR2]] {
545; CHECK-NEXT:  entry:
546; CHECK-NEXT:    [[RES:%.*]] = call i64 @normal_callee_with_intrinsic_call()
547; CHECK-NEXT:    ret i64 [[RES]]
548;
549entry:
550  %res = call i64 @normal_callee_with_intrinsic_call()
551  ret i64 %res
552}
553
554declare i64 @llvm.aarch64.sve.cntb(i32)
555
556define i64 @normal_callee_call_sme_state() {
557; CHECK-LABEL: define i64 @normal_callee_call_sme_state
558; CHECK-SAME: () #[[ATTR1]] {
559; CHECK-NEXT:  entry:
560; CHECK-NEXT:    [[RES:%.*]] = call { i64, i64 } @__arm_sme_state()
561; CHECK-NEXT:    [[RES_0:%.*]] = extractvalue { i64, i64 } [[RES]], 0
562; CHECK-NEXT:    ret i64 [[RES_0]]
563;
564entry:
565  %res = call {i64, i64} @__arm_sme_state()
566  %res.0 = extractvalue {i64, i64} %res, 0
567  ret i64 %res.0
568}
569
570declare {i64, i64} @__arm_sme_state()
571
572define i64 @streaming_caller_normal_callee_call_sme_state_dont_inline() "aarch64_pstate_sm_enabled" {
573; CHECK-LABEL: define i64 @streaming_caller_normal_callee_call_sme_state_dont_inline
574; CHECK-SAME: () #[[ATTR2]] {
575; CHECK-NEXT:  entry:
576; CHECK-NEXT:    [[RES:%.*]] = call i64 @normal_callee_call_sme_state()
577; CHECK-NEXT:    ret i64 [[RES]]
578;
579entry:
580  %res = call i64 @normal_callee_call_sme_state()
581  ret i64 %res
582}
583
584
585
586declare void @streaming_body() "aarch64_pstate_sm_enabled"
587
588define void @streaming_caller_single_streaming_callee() "aarch64_pstate_sm_enabled" {
589; CHECK-LABEL: define void @streaming_caller_single_streaming_callee
590; CHECK-SAME: () #[[ATTR2]] {
591; CHECK-NEXT:    call void @streaming_body()
592; CHECK-NEXT:    ret void
593;
594  call void @streaming_body()
595  ret void
596}
597
598define void @streaming_caller_multiple_streaming_callees() "aarch64_pstate_sm_enabled" {
599; CHECK-LABEL: define void @streaming_caller_multiple_streaming_callees
600; CHECK-SAME: () #[[ATTR2]] {
601; CHECK-NEXT:    call void @streaming_body()
602; CHECK-NEXT:    call void @streaming_body()
603; CHECK-NEXT:    ret void
604;
605  call void @streaming_body()
606  call void @streaming_body()
607  ret void
608}
609
610; Allow inlining, as inline it would not increase the number of streaming-mode changes.
611define void @streaming_caller_single_streaming_callee_inline() {
612; CHECK-LABEL: define void @streaming_caller_single_streaming_callee_inline
613; CHECK-SAME: () #[[ATTR1]] {
614; CHECK-NEXT:    call void @streaming_body()
615; CHECK-NEXT:    ret void
616;
617  call void @streaming_caller_single_streaming_callee()
618  ret void
619}
620
621; Prevent inlining, as inline it would lead to multiple streaming-mode changes.
622define void @streaming_caller_multiple_streaming_callees_dont_inline() {
623; CHECK-LABEL: define void @streaming_caller_multiple_streaming_callees_dont_inline
624; CHECK-SAME: () #[[ATTR1]] {
625; CHECK-NEXT:    call void @streaming_caller_multiple_streaming_callees()
626; CHECK-NEXT:    ret void
627;
628  call void @streaming_caller_multiple_streaming_callees()
629  ret void
630}
631
632declare void @streaming_compatible_body() "aarch64_pstate_sm_compatible"
633
634define void @streaming_caller_single_streaming_compatible_callee() "aarch64_pstate_sm_enabled" {
635; CHECK-LABEL: define void @streaming_caller_single_streaming_compatible_callee
636; CHECK-SAME: () #[[ATTR2]] {
637; CHECK-NEXT:    call void @streaming_compatible_body()
638; CHECK-NEXT:    ret void
639;
640  call void @streaming_compatible_body()
641  ret void
642}
643
644define void @streaming_caller_multiple_streaming_compatible_callees() "aarch64_pstate_sm_enabled" {
645; CHECK-LABEL: define void @streaming_caller_multiple_streaming_compatible_callees
646; CHECK-SAME: () #[[ATTR2]] {
647; CHECK-NEXT:    call void @streaming_compatible_body()
648; CHECK-NEXT:    call void @streaming_compatible_body()
649; CHECK-NEXT:    ret void
650;
651  call void @streaming_compatible_body()
652  call void @streaming_compatible_body()
653  ret void
654}
655
656; Allow inlining, as inline would remove a streaming-mode change.
657define void @streaming_caller_single_streaming_compatible_callee_inline() {
658; CHECK-LABEL: define void @streaming_caller_single_streaming_compatible_callee_inline
659; CHECK-SAME: () #[[ATTR1]] {
660; CHECK-NEXT:    call void @streaming_compatible_body()
661; CHECK-NEXT:    ret void
662;
663  call void @streaming_caller_single_streaming_compatible_callee()
664  ret void
665}
666
667; Allow inlining, as inline would remove several stremaing-mode changes.
668define void @streaming_caller_multiple_streaming_compatible_callees_inline() {
669; CHECK-LABEL: define void @streaming_caller_multiple_streaming_compatible_callees_inline
670; CHECK-SAME: () #[[ATTR1]] {
671; CHECK-NEXT:    call void @streaming_compatible_body()
672; CHECK-NEXT:    call void @streaming_compatible_body()
673; CHECK-NEXT:    ret void
674;
675  call void @streaming_caller_multiple_streaming_compatible_callees()
676  ret void
677}
678