1 ; RUN: llc -mtriple=arm64-apple-darwin -mcpu=cyclone -enable-misched=false < %s | FileCheck %s
2 ; RUN: llc -O0 -mtriple=arm64-apple-darwin < %s | FileCheck --check-prefix=FAST %s
5 define i64 @i8i16callee(i64 %a1, i64 %a2, i64 %a3, i8 signext %a4, i16 signext %a5, i64 %a6, i64 %a7, i64 %a8, i8 signext %b1, i16 signext %b2, i8 signext %b3, i8 signext %b4) nounwind readnone noinline {
7 ; CHECK-LABEL: i8i16callee:
8 ; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5.
9 ; They are i8, i16, i8 and i8.
10 ; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp, #5]
11 ; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp, #4]
12 ; CHECK-DAG: ldrsh {{w[0-9]+}}, [sp, #2]
13 ; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp]
14 ; FAST-LABEL: i8i16callee:
15 ; FAST-DAG: ldrsb {{w[0-9]+}}, [sp, #5]
16 ; FAST-DAG: ldrsb {{w[0-9]+}}, [sp, #4]
17 ; FAST-DAG: ldrsh {{w[0-9]+}}, [sp, #2]
18 ; FAST-DAG: ldrsb {{w[0-9]+}}, [sp]
19 %conv = sext i8 %a4 to i64
20 %conv3 = sext i16 %a5 to i64
21 %conv8 = sext i8 %b1 to i64
22 %conv9 = sext i16 %b2 to i64
23 %conv11 = sext i8 %b3 to i64
24 %conv13 = sext i8 %b4 to i64
25 %add10 = add i64 %a2, %a1
26 %add12 = add i64 %add10, %a3
27 %add14 = add i64 %add12, %conv
28 %add = add i64 %add14, %conv3
29 %add1 = add i64 %add, %a6
30 %add2 = add i64 %add1, %a7
31 %add4 = add i64 %add2, %a8
32 %add5 = add i64 %add4, %conv8
33 %add6 = add i64 %add5, %conv9
34 %add7 = add i64 %add6, %conv11
35 %add15 = add i64 %add7, %conv13
36 %sext = shl i64 %add15, 32
37 %conv17 = ashr exact i64 %sext, 32
41 define i32 @i8i16caller() nounwind readnone {
43 ; CHECK-LABEL: i8i16caller
44 ; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5.
45 ; They are i8, i16, i8 and i8.
46 ; CHECK-DAG: strb {{w[0-9]+}}, [sp, #5]
47 ; CHECK-DAG: strb {{w[0-9]+}}, [sp, #4]
48 ; CHECK-DAG: strh {{w[0-9]+}}, [sp, #2]
49 ; CHECK-DAG: strb {{w[0-9]+}}, [sp]
51 ; FAST-LABEL: i8i16caller
52 ; FAST: strb {{w[0-9]+}}, [sp]
53 ; FAST: strh {{w[0-9]+}}, [sp, #2]
54 ; FAST: strb {{w[0-9]+}}, [sp, #4]
55 ; FAST: strb {{w[0-9]+}}, [sp, #5]
57 %call = tail call i64 @i8i16callee(i64 0, i64 1, i64 2, i8 signext 3, i16 signext 4, i64 5, i64 6, i64 7, i8 signext 97, i16 signext 98, i8 signext 99, i8 signext 100)
58 %conv = trunc i64 %call to i32
63 define double @circle_center([2 x float] %a) nounwind ssp {
64 %call = tail call double @ext([2 x float] %a) nounwind
65 ; CHECK-LABEL: circle_center
69 declare double @ext([2 x float])
72 ; 16-byte vector should be aligned at 16-byte when passing on stack.
73 ; A double argument will be passed on stack, so vecotr should be at sp+16.
74 define double @fixed_4i(<4 x i32>* nocapture %in) nounwind {
76 ; CHECK-LABEL: fixed_4i
77 ; CHECK: str [[REG_1:q[0-9]+]], [sp, #16]
78 ; FAST-LABEL: fixed_4i
80 ; FAST: mov x[[ADDR:[0-9]+]], sp
81 ; FAST: str [[REG_1:q[0-9]+]], [x[[ADDR]], #16]
82 %0 = load <4 x i32>* %in, align 16
83 %call = tail call double @args_vec_4i(double 3.000000e+00, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, <4 x i32> %0, double 3.000000e+00, <4 x i32> %0, i8 signext 3)
86 declare double @args_vec_4i(double, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, double, <4 x i32>, i8 signext)
89 ; d8 at sp, i in register w0.
90 @g_d = common global double 0.000000e+00, align 8
91 define void @test1(float %f1, double %d1, double %d2, double %d3, double %d4,
92 double %d5, double %d6, double %d7, double %d8, i32 %i) nounwind ssp {
95 ; CHECK: ldr [[REG_1:d[0-9]+]], [sp]
96 ; CHECK: scvtf [[REG_2:s[0-9]+]], w0
97 ; CHECK: fadd s0, [[REG_2]], s0
98 %conv = sitofp i32 %i to float
99 %add = fadd float %conv, %f1
100 %conv1 = fpext float %add to double
101 %add2 = fadd double %conv1, %d7
102 %add3 = fadd double %add2, %d8
103 store double %add3, double* @g_d, align 8
107 ; i9 at sp, d1 in register s0.
108 define void @test2(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
109 i32 %i7, i32 %i8, i32 %i9, float %d1) nounwind ssp {
112 ; CHECK: scvtf [[REG_2:s[0-9]+]], w0
113 ; CHECK: fadd s0, [[REG_2]], s0
114 ; CHECK: ldr [[REG_1:s[0-9]+]], [sp]
115 %conv = sitofp i32 %i1 to float
116 %add = fadd float %conv, %d1
117 %conv1 = fpext float %add to double
118 %conv2 = sitofp i32 %i8 to double
119 %add3 = fadd double %conv2, %conv1
120 %conv4 = sitofp i32 %i9 to double
121 %add5 = fadd double %conv4, %add3
122 store double %add5, double* @g_d, align 8
127 ; Check alignment on stack for v64, f64, i64, f32, i32.
128 define double @test3(<2 x i32>* nocapture %in) nounwind {
131 ; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
133 ; FAST: sub sp, sp, #32
134 ; FAST: mov x[[ADDR:[0-9]+]], sp
135 ; FAST: str [[REG_1:d[0-9]+]], [x[[ADDR]], #8]
136 %0 = load <2 x i32>* %in, align 8
137 %call = tail call double @args_vec_2i(double 3.000000e+00, <2 x i32> %0,
138 <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0,
139 <2 x i32> %0, float 3.000000e+00, <2 x i32> %0, i8 signext 3)
142 declare double @args_vec_2i(double, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>,
143 <2 x i32>, <2 x i32>, <2 x i32>, float, <2 x i32>, i8 signext)
145 define double @test4(double* nocapture %in) nounwind {
148 ; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
149 ; CHECK: str [[REG_2:w[0-9]+]], [sp]
150 ; CHECK: orr w0, wzr, #0x3
151 %0 = load double* %in, align 8
152 %call = tail call double @args_f64(double 3.000000e+00, double %0, double %0,
153 double %0, double %0, double %0, double %0, double %0,
154 float 3.000000e+00, double %0, i8 signext 3)
157 declare double @args_f64(double, double, double, double, double, double, double,
158 double, float, double, i8 signext)
160 define i64 @test5(i64* nocapture %in) nounwind {
163 ; CHECK: strb [[REG_3:w[0-9]+]], [sp, #16]
164 ; CHECK: str [[REG_1:x[0-9]+]], [sp, #8]
165 ; CHECK: str [[REG_2:w[0-9]+]], [sp]
166 %0 = load i64* %in, align 8
167 %call = tail call i64 @args_i64(i64 3, i64 %0, i64 %0, i64 %0, i64 %0, i64 %0,
168 i64 %0, i64 %0, i32 3, i64 %0, i8 signext 3)
171 declare i64 @args_i64(i64, i64, i64, i64, i64, i64, i64, i64, i32, i64,
174 define i32 @test6(float* nocapture %in) nounwind {
177 ; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
178 ; CHECK: str [[REG_1:s[0-9]+]], [sp, #4]
179 ; CHECK: strh [[REG_3:w[0-9]+]], [sp]
180 %0 = load float* %in, align 4
181 %call = tail call i32 @args_f32(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
182 i32 7, i32 8, float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
183 float 6.0, float 7.0, float 8.0, i16 signext 3, float %0,
187 declare i32 @args_f32(i32, i32, i32, i32, i32, i32, i32, i32,
188 float, float, float, float, float, float, float, float,
189 i16 signext, float, i8 signext)
191 define i32 @test7(i32* nocapture %in) nounwind {
194 ; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
195 ; CHECK: str [[REG_1:w[0-9]+]], [sp, #4]
196 ; CHECK: strh [[REG_3:w[0-9]+]], [sp]
197 %0 = load i32* %in, align 4
198 %call = tail call i32 @args_i32(i32 3, i32 %0, i32 %0, i32 %0, i32 %0, i32 %0,
199 i32 %0, i32 %0, i16 signext 3, i32 %0, i8 signext 4)
202 declare i32 @args_i32(i32, i32, i32, i32, i32, i32, i32, i32, i16 signext, i32,
205 define i32 @test8(i32 %argc, i8** nocapture %argv) nounwind {
208 ; CHECK: strb {{w[0-9]+}}, [sp, #3]
209 ; CHECK: strb wzr, [sp, #2]
210 ; CHECK: strb {{w[0-9]+}}, [sp, #1]
211 ; CHECK: strb wzr, [sp]
214 ; FAST: strb {{w[0-9]+}}, [sp]
215 ; FAST: strb {{w[0-9]+}}, [sp, #1]
216 ; FAST: strb {{w[0-9]+}}, [sp, #2]
217 ; FAST: strb {{w[0-9]+}}, [sp, #3]
219 tail call void @args_i1(i1 zeroext false, i1 zeroext true, i1 zeroext false,
220 i1 zeroext true, i1 zeroext false, i1 zeroext true,
221 i1 zeroext false, i1 zeroext true, i1 zeroext false,
222 i1 zeroext true, i1 zeroext false, i1 zeroext true)
226 declare void @args_i1(i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
227 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
228 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext)
230 define i32 @i1_stack_incoming(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f,
231 i64 %g, i64 %h, i64 %i, i1 zeroext %j) {
232 ; CHECK-LABEL: i1_stack_incoming:
233 ; CHECK: ldrb w0, [sp, #8]
235 %v = zext i1 %j to i32