xref: /llvm-project/llvm/test/CodeGen/AArch64/sve-tailcall.ll (revision c5253aa136ac6ba683b367b2bae0dde1a543d1df)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64 -mattr=+sve < %s | FileCheck %s
3
4; Check that a tail call from an SVE function to another SVE function
5; can use a tail-call, as the same registers will be preserved by the
6; callee.
7define <vscale x 4 x i32> @sve_caller_sve_callee() nounwind {
8; CHECK-LABEL: sve_caller_sve_callee:
9; CHECK:       // %bb.0:
10; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
11; CHECK-NEXT:    addvl sp, sp, #-2
12; CHECK-NEXT:    str z10, [sp] // 16-byte Folded Spill
13; CHECK-NEXT:    str z9, [sp, #1, mul vl] // 16-byte Folded Spill
14; CHECK-NEXT:    //APP
15; CHECK-NEXT:    //NO_APP
16; CHECK-NEXT:    ldr z10, [sp] // 16-byte Folded Reload
17; CHECK-NEXT:    ldr z9, [sp, #1, mul vl] // 16-byte Folded Reload
18; CHECK-NEXT:    addvl sp, sp, #2
19; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
20; CHECK-NEXT:    b sve_callee
21  tail call void asm sideeffect "", "~{z9},~{z10}"()
22  %call = tail call <vscale x 4 x i32> @sve_callee()
23  ret <vscale x 4 x i32> %call
24}
25
26define <vscale x 4 x i32> @sve_caller_sve_callee_fastcc() nounwind {
27; CHECK-LABEL: sve_caller_sve_callee_fastcc:
28; CHECK:       // %bb.0:
29; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
30; CHECK-NEXT:    addvl sp, sp, #-2
31; CHECK-NEXT:    str z10, [sp] // 16-byte Folded Spill
32; CHECK-NEXT:    str z9, [sp, #1, mul vl] // 16-byte Folded Spill
33; CHECK-NEXT:    //APP
34; CHECK-NEXT:    //NO_APP
35; CHECK-NEXT:    ldr z10, [sp] // 16-byte Folded Reload
36; CHECK-NEXT:    ldr z9, [sp, #1, mul vl] // 16-byte Folded Reload
37; CHECK-NEXT:    addvl sp, sp, #2
38; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
39; CHECK-NEXT:    b sve_callee
40  tail call void asm sideeffect "", "~{z9},~{z10}"()
41  %call = tail call fastcc <vscale x 4 x i32> @sve_callee()
42  ret <vscale x 4 x i32> %call
43}
44
45declare <vscale x 4 x i32> @sve_callee()
46
47; Check that a tail call from an SVE function to a non-SVE function
48; does not use a tail-call, because after the call many of the SVE
49; registers may be clobbered and needs to be restored.
50define i32 @sve_caller_non_sve_callee(<vscale x 4 x i32> %arg) nounwind {
51; CHECK-LABEL: sve_caller_non_sve_callee:
52; CHECK:       // %bb.0:
53; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
54; CHECK-NEXT:    addvl sp, sp, #-18
55; CHECK-NEXT:    str p15, [sp, #4, mul vl] // 2-byte Folded Spill
56; CHECK-NEXT:    str p14, [sp, #5, mul vl] // 2-byte Folded Spill
57; CHECK-NEXT:    str p13, [sp, #6, mul vl] // 2-byte Folded Spill
58; CHECK-NEXT:    str p12, [sp, #7, mul vl] // 2-byte Folded Spill
59; CHECK-NEXT:    str p11, [sp, #8, mul vl] // 2-byte Folded Spill
60; CHECK-NEXT:    str p10, [sp, #9, mul vl] // 2-byte Folded Spill
61; CHECK-NEXT:    str p9, [sp, #10, mul vl] // 2-byte Folded Spill
62; CHECK-NEXT:    str p8, [sp, #11, mul vl] // 2-byte Folded Spill
63; CHECK-NEXT:    str p7, [sp, #12, mul vl] // 2-byte Folded Spill
64; CHECK-NEXT:    str p6, [sp, #13, mul vl] // 2-byte Folded Spill
65; CHECK-NEXT:    str p5, [sp, #14, mul vl] // 2-byte Folded Spill
66; CHECK-NEXT:    str p4, [sp, #15, mul vl] // 2-byte Folded Spill
67; CHECK-NEXT:    str z23, [sp, #2, mul vl] // 16-byte Folded Spill
68; CHECK-NEXT:    str z22, [sp, #3, mul vl] // 16-byte Folded Spill
69; CHECK-NEXT:    str z21, [sp, #4, mul vl] // 16-byte Folded Spill
70; CHECK-NEXT:    str z20, [sp, #5, mul vl] // 16-byte Folded Spill
71; CHECK-NEXT:    str z19, [sp, #6, mul vl] // 16-byte Folded Spill
72; CHECK-NEXT:    str z18, [sp, #7, mul vl] // 16-byte Folded Spill
73; CHECK-NEXT:    str z17, [sp, #8, mul vl] // 16-byte Folded Spill
74; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
75; CHECK-NEXT:    str z15, [sp, #10, mul vl] // 16-byte Folded Spill
76; CHECK-NEXT:    str z14, [sp, #11, mul vl] // 16-byte Folded Spill
77; CHECK-NEXT:    str z13, [sp, #12, mul vl] // 16-byte Folded Spill
78; CHECK-NEXT:    str z12, [sp, #13, mul vl] // 16-byte Folded Spill
79; CHECK-NEXT:    str z11, [sp, #14, mul vl] // 16-byte Folded Spill
80; CHECK-NEXT:    str z10, [sp, #15, mul vl] // 16-byte Folded Spill
81; CHECK-NEXT:    str z9, [sp, #16, mul vl] // 16-byte Folded Spill
82; CHECK-NEXT:    str z8, [sp, #17, mul vl] // 16-byte Folded Spill
83; CHECK-NEXT:    //APP
84; CHECK-NEXT:    //NO_APP
85; CHECK-NEXT:    bl non_sve_callee
86; CHECK-NEXT:    ldr z23, [sp, #2, mul vl] // 16-byte Folded Reload
87; CHECK-NEXT:    ldr z22, [sp, #3, mul vl] // 16-byte Folded Reload
88; CHECK-NEXT:    ldr z21, [sp, #4, mul vl] // 16-byte Folded Reload
89; CHECK-NEXT:    ldr z20, [sp, #5, mul vl] // 16-byte Folded Reload
90; CHECK-NEXT:    ldr z19, [sp, #6, mul vl] // 16-byte Folded Reload
91; CHECK-NEXT:    ldr z18, [sp, #7, mul vl] // 16-byte Folded Reload
92; CHECK-NEXT:    ldr z17, [sp, #8, mul vl] // 16-byte Folded Reload
93; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
94; CHECK-NEXT:    ldr z15, [sp, #10, mul vl] // 16-byte Folded Reload
95; CHECK-NEXT:    ldr z14, [sp, #11, mul vl] // 16-byte Folded Reload
96; CHECK-NEXT:    ldr z13, [sp, #12, mul vl] // 16-byte Folded Reload
97; CHECK-NEXT:    ldr z12, [sp, #13, mul vl] // 16-byte Folded Reload
98; CHECK-NEXT:    ldr z11, [sp, #14, mul vl] // 16-byte Folded Reload
99; CHECK-NEXT:    ldr z10, [sp, #15, mul vl] // 16-byte Folded Reload
100; CHECK-NEXT:    ldr z9, [sp, #16, mul vl] // 16-byte Folded Reload
101; CHECK-NEXT:    ldr z8, [sp, #17, mul vl] // 16-byte Folded Reload
102; CHECK-NEXT:    ldr p15, [sp, #4, mul vl] // 2-byte Folded Reload
103; CHECK-NEXT:    ldr p14, [sp, #5, mul vl] // 2-byte Folded Reload
104; CHECK-NEXT:    ldr p13, [sp, #6, mul vl] // 2-byte Folded Reload
105; CHECK-NEXT:    ldr p12, [sp, #7, mul vl] // 2-byte Folded Reload
106; CHECK-NEXT:    ldr p11, [sp, #8, mul vl] // 2-byte Folded Reload
107; CHECK-NEXT:    ldr p10, [sp, #9, mul vl] // 2-byte Folded Reload
108; CHECK-NEXT:    ldr p9, [sp, #10, mul vl] // 2-byte Folded Reload
109; CHECK-NEXT:    ldr p8, [sp, #11, mul vl] // 2-byte Folded Reload
110; CHECK-NEXT:    ldr p7, [sp, #12, mul vl] // 2-byte Folded Reload
111; CHECK-NEXT:    ldr p6, [sp, #13, mul vl] // 2-byte Folded Reload
112; CHECK-NEXT:    ldr p5, [sp, #14, mul vl] // 2-byte Folded Reload
113; CHECK-NEXT:    ldr p4, [sp, #15, mul vl] // 2-byte Folded Reload
114; CHECK-NEXT:    addvl sp, sp, #18
115; CHECK-NEXT:    ldp x29, x30, [sp], #16 // 16-byte Folded Reload
116; CHECK-NEXT:    ret
117  tail call void asm sideeffect "", "~{z9},~{z10}"()
118  %call = tail call i32 @non_sve_callee()
119  ret i32 %call
120}
121
122; Check that a tail call from an SVE function to a non-SVE function
123; does not use a tail-call, because after the call many of the SVE
124; registers may be clobbered and needs to be restored.
125define i32 @sve_caller_non_sve_callee_fastcc(<vscale x 4 x i32> %arg) nounwind {
126; CHECK-LABEL: sve_caller_non_sve_callee_fastcc:
127; CHECK:       // %bb.0:
128; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
129; CHECK-NEXT:    addvl sp, sp, #-18
130; CHECK-NEXT:    str p15, [sp, #4, mul vl] // 2-byte Folded Spill
131; CHECK-NEXT:    str p14, [sp, #5, mul vl] // 2-byte Folded Spill
132; CHECK-NEXT:    str p13, [sp, #6, mul vl] // 2-byte Folded Spill
133; CHECK-NEXT:    str p12, [sp, #7, mul vl] // 2-byte Folded Spill
134; CHECK-NEXT:    str p11, [sp, #8, mul vl] // 2-byte Folded Spill
135; CHECK-NEXT:    str p10, [sp, #9, mul vl] // 2-byte Folded Spill
136; CHECK-NEXT:    str p9, [sp, #10, mul vl] // 2-byte Folded Spill
137; CHECK-NEXT:    str p8, [sp, #11, mul vl] // 2-byte Folded Spill
138; CHECK-NEXT:    str p7, [sp, #12, mul vl] // 2-byte Folded Spill
139; CHECK-NEXT:    str p6, [sp, #13, mul vl] // 2-byte Folded Spill
140; CHECK-NEXT:    str p5, [sp, #14, mul vl] // 2-byte Folded Spill
141; CHECK-NEXT:    str p4, [sp, #15, mul vl] // 2-byte Folded Spill
142; CHECK-NEXT:    str z23, [sp, #2, mul vl] // 16-byte Folded Spill
143; CHECK-NEXT:    str z22, [sp, #3, mul vl] // 16-byte Folded Spill
144; CHECK-NEXT:    str z21, [sp, #4, mul vl] // 16-byte Folded Spill
145; CHECK-NEXT:    str z20, [sp, #5, mul vl] // 16-byte Folded Spill
146; CHECK-NEXT:    str z19, [sp, #6, mul vl] // 16-byte Folded Spill
147; CHECK-NEXT:    str z18, [sp, #7, mul vl] // 16-byte Folded Spill
148; CHECK-NEXT:    str z17, [sp, #8, mul vl] // 16-byte Folded Spill
149; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
150; CHECK-NEXT:    str z15, [sp, #10, mul vl] // 16-byte Folded Spill
151; CHECK-NEXT:    str z14, [sp, #11, mul vl] // 16-byte Folded Spill
152; CHECK-NEXT:    str z13, [sp, #12, mul vl] // 16-byte Folded Spill
153; CHECK-NEXT:    str z12, [sp, #13, mul vl] // 16-byte Folded Spill
154; CHECK-NEXT:    str z11, [sp, #14, mul vl] // 16-byte Folded Spill
155; CHECK-NEXT:    str z10, [sp, #15, mul vl] // 16-byte Folded Spill
156; CHECK-NEXT:    str z9, [sp, #16, mul vl] // 16-byte Folded Spill
157; CHECK-NEXT:    str z8, [sp, #17, mul vl] // 16-byte Folded Spill
158; CHECK-NEXT:    //APP
159; CHECK-NEXT:    //NO_APP
160; CHECK-NEXT:    bl non_sve_callee
161; CHECK-NEXT:    ldr z23, [sp, #2, mul vl] // 16-byte Folded Reload
162; CHECK-NEXT:    ldr z22, [sp, #3, mul vl] // 16-byte Folded Reload
163; CHECK-NEXT:    ldr z21, [sp, #4, mul vl] // 16-byte Folded Reload
164; CHECK-NEXT:    ldr z20, [sp, #5, mul vl] // 16-byte Folded Reload
165; CHECK-NEXT:    ldr z19, [sp, #6, mul vl] // 16-byte Folded Reload
166; CHECK-NEXT:    ldr z18, [sp, #7, mul vl] // 16-byte Folded Reload
167; CHECK-NEXT:    ldr z17, [sp, #8, mul vl] // 16-byte Folded Reload
168; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
169; CHECK-NEXT:    ldr z15, [sp, #10, mul vl] // 16-byte Folded Reload
170; CHECK-NEXT:    ldr z14, [sp, #11, mul vl] // 16-byte Folded Reload
171; CHECK-NEXT:    ldr z13, [sp, #12, mul vl] // 16-byte Folded Reload
172; CHECK-NEXT:    ldr z12, [sp, #13, mul vl] // 16-byte Folded Reload
173; CHECK-NEXT:    ldr z11, [sp, #14, mul vl] // 16-byte Folded Reload
174; CHECK-NEXT:    ldr z10, [sp, #15, mul vl] // 16-byte Folded Reload
175; CHECK-NEXT:    ldr z9, [sp, #16, mul vl] // 16-byte Folded Reload
176; CHECK-NEXT:    ldr z8, [sp, #17, mul vl] // 16-byte Folded Reload
177; CHECK-NEXT:    ldr p15, [sp, #4, mul vl] // 2-byte Folded Reload
178; CHECK-NEXT:    ldr p14, [sp, #5, mul vl] // 2-byte Folded Reload
179; CHECK-NEXT:    ldr p13, [sp, #6, mul vl] // 2-byte Folded Reload
180; CHECK-NEXT:    ldr p12, [sp, #7, mul vl] // 2-byte Folded Reload
181; CHECK-NEXT:    ldr p11, [sp, #8, mul vl] // 2-byte Folded Reload
182; CHECK-NEXT:    ldr p10, [sp, #9, mul vl] // 2-byte Folded Reload
183; CHECK-NEXT:    ldr p9, [sp, #10, mul vl] // 2-byte Folded Reload
184; CHECK-NEXT:    ldr p8, [sp, #11, mul vl] // 2-byte Folded Reload
185; CHECK-NEXT:    ldr p7, [sp, #12, mul vl] // 2-byte Folded Reload
186; CHECK-NEXT:    ldr p6, [sp, #13, mul vl] // 2-byte Folded Reload
187; CHECK-NEXT:    ldr p5, [sp, #14, mul vl] // 2-byte Folded Reload
188; CHECK-NEXT:    ldr p4, [sp, #15, mul vl] // 2-byte Folded Reload
189; CHECK-NEXT:    addvl sp, sp, #18
190; CHECK-NEXT:    ldp x29, x30, [sp], #16 // 16-byte Folded Reload
191; CHECK-NEXT:    ret
192  tail call void asm sideeffect "", "~{z9},~{z10}"()
193  %call = tail call fastcc i32 @non_sve_callee()
194  ret i32 %call
195}
196
197declare i32 @non_sve_callee()
198