1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64 -mattr=+sve < %s 2>%t | FileCheck %s
3; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
4
5; If this check fails please read test/CodeGen/AArch64/README for instructions on how to resolve it.
6; WARN-NOT: warning
7
8; Check that a tail call from an SVE function to another SVE function
9; can use a tail-call, as the same registers will be preserved by the
10; callee.
11define <vscale x 4 x i32> @sve_caller_sve_callee() nounwind {
12; CHECK-LABEL: sve_caller_sve_callee:
13; CHECK:       // %bb.0:
14; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
15; CHECK-NEXT:    addvl sp, sp, #-2
16; CHECK-NEXT:    str z10, [sp] // 16-byte Folded Spill
17; CHECK-NEXT:    str z9, [sp, #1, mul vl] // 16-byte Folded Spill
18; CHECK-NEXT:    //APP
19; CHECK-NEXT:    //NO_APP
20; CHECK-NEXT:    ldr z10, [sp] // 16-byte Folded Reload
21; CHECK-NEXT:    ldr z9, [sp, #1, mul vl] // 16-byte Folded Reload
22; CHECK-NEXT:    addvl sp, sp, #2
23; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
24; CHECK-NEXT:    b sve_callee
25  tail call void asm sideeffect "", "~{z9},~{z10}"()
26  %call = tail call <vscale x 4 x i32> @sve_callee()
27  ret <vscale x 4 x i32> %call
28}
29
30declare <vscale x 4 x i32> @sve_callee()
31
32; Check that a tail call from an SVE function to a non-SVE function
33; does not use a tail-call, because after the call many of the SVE
34; registers may be clobbered and needs to be restored.
35define i32 @sve_caller_non_sve_callee(<vscale x 4 x i32> %arg) nounwind {
36; CHECK-LABEL: sve_caller_non_sve_callee:
37; CHECK:       // %bb.0:
38; CHECK-NEXT:    stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
39; CHECK-NEXT:    addvl sp, sp, #-18
40; CHECK-NEXT:    str p15, [sp, #4, mul vl] // 2-byte Folded Spill
41; CHECK-NEXT:    str p14, [sp, #5, mul vl] // 2-byte Folded Spill
42; CHECK-NEXT:    str p13, [sp, #6, mul vl] // 2-byte Folded Spill
43; CHECK-NEXT:    str p12, [sp, #7, mul vl] // 2-byte Folded Spill
44; CHECK-NEXT:    str p11, [sp, #8, mul vl] // 2-byte Folded Spill
45; CHECK-NEXT:    str p10, [sp, #9, mul vl] // 2-byte Folded Spill
46; CHECK-NEXT:    str p9, [sp, #10, mul vl] // 2-byte Folded Spill
47; CHECK-NEXT:    str p8, [sp, #11, mul vl] // 2-byte Folded Spill
48; CHECK-NEXT:    str p7, [sp, #12, mul vl] // 2-byte Folded Spill
49; CHECK-NEXT:    str p6, [sp, #13, mul vl] // 2-byte Folded Spill
50; CHECK-NEXT:    str p5, [sp, #14, mul vl] // 2-byte Folded Spill
51; CHECK-NEXT:    str p4, [sp, #15, mul vl] // 2-byte Folded Spill
52; CHECK-NEXT:    str z23, [sp, #2, mul vl] // 16-byte Folded Spill
53; CHECK-NEXT:    str z22, [sp, #3, mul vl] // 16-byte Folded Spill
54; CHECK-NEXT:    str z21, [sp, #4, mul vl] // 16-byte Folded Spill
55; CHECK-NEXT:    str z20, [sp, #5, mul vl] // 16-byte Folded Spill
56; CHECK-NEXT:    str z19, [sp, #6, mul vl] // 16-byte Folded Spill
57; CHECK-NEXT:    str z18, [sp, #7, mul vl] // 16-byte Folded Spill
58; CHECK-NEXT:    str z17, [sp, #8, mul vl] // 16-byte Folded Spill
59; CHECK-NEXT:    str z16, [sp, #9, mul vl] // 16-byte Folded Spill
60; CHECK-NEXT:    str z15, [sp, #10, mul vl] // 16-byte Folded Spill
61; CHECK-NEXT:    str z14, [sp, #11, mul vl] // 16-byte Folded Spill
62; CHECK-NEXT:    str z13, [sp, #12, mul vl] // 16-byte Folded Spill
63; CHECK-NEXT:    str z12, [sp, #13, mul vl] // 16-byte Folded Spill
64; CHECK-NEXT:    str z11, [sp, #14, mul vl] // 16-byte Folded Spill
65; CHECK-NEXT:    str z10, [sp, #15, mul vl] // 16-byte Folded Spill
66; CHECK-NEXT:    str z9, [sp, #16, mul vl] // 16-byte Folded Spill
67; CHECK-NEXT:    str z8, [sp, #17, mul vl] // 16-byte Folded Spill
68; CHECK-NEXT:    //APP
69; CHECK-NEXT:    //NO_APP
70; CHECK-NEXT:    bl non_sve_callee
71; CHECK-NEXT:    ldr p15, [sp, #4, mul vl] // 2-byte Folded Reload
72; CHECK-NEXT:    ldr p14, [sp, #5, mul vl] // 2-byte Folded Reload
73; CHECK-NEXT:    ldr p13, [sp, #6, mul vl] // 2-byte Folded Reload
74; CHECK-NEXT:    ldr p12, [sp, #7, mul vl] // 2-byte Folded Reload
75; CHECK-NEXT:    ldr p11, [sp, #8, mul vl] // 2-byte Folded Reload
76; CHECK-NEXT:    ldr p10, [sp, #9, mul vl] // 2-byte Folded Reload
77; CHECK-NEXT:    ldr p9, [sp, #10, mul vl] // 2-byte Folded Reload
78; CHECK-NEXT:    ldr p8, [sp, #11, mul vl] // 2-byte Folded Reload
79; CHECK-NEXT:    ldr p7, [sp, #12, mul vl] // 2-byte Folded Reload
80; CHECK-NEXT:    ldr p6, [sp, #13, mul vl] // 2-byte Folded Reload
81; CHECK-NEXT:    ldr p5, [sp, #14, mul vl] // 2-byte Folded Reload
82; CHECK-NEXT:    ldr p4, [sp, #15, mul vl] // 2-byte Folded Reload
83; CHECK-NEXT:    ldr z23, [sp, #2, mul vl] // 16-byte Folded Reload
84; CHECK-NEXT:    ldr z22, [sp, #3, mul vl] // 16-byte Folded Reload
85; CHECK-NEXT:    ldr z21, [sp, #4, mul vl] // 16-byte Folded Reload
86; CHECK-NEXT:    ldr z20, [sp, #5, mul vl] // 16-byte Folded Reload
87; CHECK-NEXT:    ldr z19, [sp, #6, mul vl] // 16-byte Folded Reload
88; CHECK-NEXT:    ldr z18, [sp, #7, mul vl] // 16-byte Folded Reload
89; CHECK-NEXT:    ldr z17, [sp, #8, mul vl] // 16-byte Folded Reload
90; CHECK-NEXT:    ldr z16, [sp, #9, mul vl] // 16-byte Folded Reload
91; CHECK-NEXT:    ldr z15, [sp, #10, mul vl] // 16-byte Folded Reload
92; CHECK-NEXT:    ldr z14, [sp, #11, mul vl] // 16-byte Folded Reload
93; CHECK-NEXT:    ldr z13, [sp, #12, mul vl] // 16-byte Folded Reload
94; CHECK-NEXT:    ldr z12, [sp, #13, mul vl] // 16-byte Folded Reload
95; CHECK-NEXT:    ldr z11, [sp, #14, mul vl] // 16-byte Folded Reload
96; CHECK-NEXT:    ldr z10, [sp, #15, mul vl] // 16-byte Folded Reload
97; CHECK-NEXT:    ldr z9, [sp, #16, mul vl] // 16-byte Folded Reload
98; CHECK-NEXT:    ldr z8, [sp, #17, mul vl] // 16-byte Folded Reload
99; CHECK-NEXT:    addvl sp, sp, #18
100; CHECK-NEXT:    ldp x29, x30, [sp], #16 // 16-byte Folded Reload
101; CHECK-NEXT:    ret
102  tail call void asm sideeffect "", "~{z9},~{z10}"()
103  %call = tail call i32 @non_sve_callee()
104  ret i32 %call
105}
106
107declare i32 @non_sve_callee()
108