blob: b48e35747564e8abd871154f905603e45232119e [file] [log] [blame]
Juergen Ributzka88f6faf2014-07-22 23:14:54 +00001; RUN: llc < %s -march=arm64 -mcpu=cyclone -enable-misched=false | FileCheck %s
Tim Northover00ed9962014-03-29 10:18:08 +00002; RUN: llc < %s -O0 | FileCheck -check-prefix=FAST %s
Tim Northover6890add2014-06-03 13:54:53 +00003; REQUIRES: asserts
Tim Northover00ed9962014-03-29 10:18:08 +00004target triple = "arm64-apple-darwin"
5
6; rdar://9932559
7define 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 {
8entry:
9; CHECK-LABEL: i8i16callee:
10; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5.
11; They are i8, i16, i8 and i8.
Tim Northover6890add2014-06-03 13:54:53 +000012; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp, #5]
13; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp, #4]
14; CHECK-DAG: ldrsh {{w[0-9]+}}, [sp, #2]
15; CHECK-DAG: ldrsb {{w[0-9]+}}, [sp]
Tim Northover00ed9962014-03-29 10:18:08 +000016; FAST-LABEL: i8i16callee:
Tim Northover6890add2014-06-03 13:54:53 +000017; FAST-DAG: ldrsb {{w[0-9]+}}, [sp, #5]
18; FAST-DAG: ldrsb {{w[0-9]+}}, [sp, #4]
19; FAST-DAG: ldrsh {{w[0-9]+}}, [sp, #2]
20; FAST-DAG: ldrsb {{w[0-9]+}}, [sp]
Tim Northover00ed9962014-03-29 10:18:08 +000021 %conv = sext i8 %a4 to i64
22 %conv3 = sext i16 %a5 to i64
23 %conv8 = sext i8 %b1 to i64
24 %conv9 = sext i16 %b2 to i64
25 %conv11 = sext i8 %b3 to i64
26 %conv13 = sext i8 %b4 to i64
27 %add10 = add i64 %a2, %a1
28 %add12 = add i64 %add10, %a3
29 %add14 = add i64 %add12, %conv
30 %add = add i64 %add14, %conv3
31 %add1 = add i64 %add, %a6
32 %add2 = add i64 %add1, %a7
33 %add4 = add i64 %add2, %a8
34 %add5 = add i64 %add4, %conv8
35 %add6 = add i64 %add5, %conv9
36 %add7 = add i64 %add6, %conv11
37 %add15 = add i64 %add7, %conv13
38 %sext = shl i64 %add15, 32
39 %conv17 = ashr exact i64 %sext, 32
40 ret i64 %conv17
41}
42
43define i32 @i8i16caller() nounwind readnone {
44entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +000045; CHECK-LABEL: i8i16caller
Tim Northover00ed9962014-03-29 10:18:08 +000046; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5.
47; They are i8, i16, i8 and i8.
Tim Northover6890add2014-06-03 13:54:53 +000048; CHECK-DAG: strb {{w[0-9]+}}, [sp, #5]
49; CHECK-DAG: strb {{w[0-9]+}}, [sp, #4]
50; CHECK-DAG: strh {{w[0-9]+}}, [sp, #2]
51; CHECK-DAG: strb {{w[0-9]+}}, [sp]
Tim Northover00ed9962014-03-29 10:18:08 +000052; CHECK: bl
Juergen Ributzka88f6faf2014-07-22 23:14:54 +000053; FAST-LABEL: i8i16caller
Tim Northover00ed9962014-03-29 10:18:08 +000054; FAST: strb {{w[0-9]+}}, [sp]
55; FAST: strh {{w[0-9]+}}, [sp, #2]
56; FAST: strb {{w[0-9]+}}, [sp, #4]
57; FAST: strb {{w[0-9]+}}, [sp, #5]
58; FAST: bl
59 %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)
60 %conv = trunc i64 %call to i32
61 ret i32 %conv
62}
63
64; rdar://12651543
65define double @circle_center([2 x float] %a) nounwind ssp {
66 %call = tail call double @ext([2 x float] %a) nounwind
Juergen Ributzka88f6faf2014-07-22 23:14:54 +000067; CHECK-LABEL: circle_center
Tim Northover00ed9962014-03-29 10:18:08 +000068; CHECK: bl
69 ret double %call
70}
71declare double @ext([2 x float])
72
73; rdar://12656141
74; 16-byte vector should be aligned at 16-byte when passing on stack.
75; A double argument will be passed on stack, so vecotr should be at sp+16.
76define double @fixed_4i(<4 x i32>* nocapture %in) nounwind {
77entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +000078; CHECK-LABEL: fixed_4i
Tim Northover00ed9962014-03-29 10:18:08 +000079; CHECK: str [[REG_1:q[0-9]+]], [sp, #16]
Juergen Ributzka88f6faf2014-07-22 23:14:54 +000080; FAST-LABEL: fixed_4i
Juergen Ributzka2581fa52014-07-22 23:14:58 +000081; FAST: sub sp, sp
Tim Northover00ed9962014-03-29 10:18:08 +000082; FAST: mov x[[ADDR:[0-9]+]], sp
83; FAST: str [[REG_1:q[0-9]+]], [x[[ADDR]], #16]
84 %0 = load <4 x i32>* %in, align 16
85 %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 ret double %call
87}
88declare 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
90; rdar://12695237
91; d8 at sp, i in register w0.
92@g_d = common global double 0.000000e+00, align 8
93define void @test1(float %f1, double %d1, double %d2, double %d3, double %d4,
94 double %d5, double %d6, double %d7, double %d8, i32 %i) nounwind ssp {
95entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +000096; CHECK-LABEL: test1
Tim Northover00ed9962014-03-29 10:18:08 +000097; CHECK: ldr [[REG_1:d[0-9]+]], [sp]
98; CHECK: scvtf [[REG_2:s[0-9]+]], w0
99; CHECK: fadd s0, [[REG_2]], s0
100 %conv = sitofp i32 %i to float
101 %add = fadd float %conv, %f1
102 %conv1 = fpext float %add to double
103 %add2 = fadd double %conv1, %d7
104 %add3 = fadd double %add2, %d8
105 store double %add3, double* @g_d, align 8
106 ret void
107}
108
109; i9 at sp, d1 in register s0.
110define void @test2(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
111 i32 %i7, i32 %i8, i32 %i9, float %d1) nounwind ssp {
112entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000113; CHECK-LABEL: test2
Tim Northover00ed9962014-03-29 10:18:08 +0000114; CHECK: scvtf [[REG_2:s[0-9]+]], w0
115; CHECK: fadd s0, [[REG_2]], s0
116; CHECK: ldr [[REG_1:s[0-9]+]], [sp]
117 %conv = sitofp i32 %i1 to float
118 %add = fadd float %conv, %d1
119 %conv1 = fpext float %add to double
120 %conv2 = sitofp i32 %i8 to double
121 %add3 = fadd double %conv2, %conv1
122 %conv4 = sitofp i32 %i9 to double
123 %add5 = fadd double %conv4, %add3
124 store double %add5, double* @g_d, align 8
125 ret void
126}
127
128; rdar://12648441
129; Check alignment on stack for v64, f64, i64, f32, i32.
130define double @test3(<2 x i32>* nocapture %in) nounwind {
131entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000132; CHECK-LABEL: test3
Tim Northover00ed9962014-03-29 10:18:08 +0000133; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000134; FAST-LABEL: test3
Bradley Smith6f1aa592014-04-09 14:43:50 +0000135; FAST: sub sp, sp, #32
Tim Northover00ed9962014-03-29 10:18:08 +0000136; FAST: mov x[[ADDR:[0-9]+]], sp
137; FAST: str [[REG_1:d[0-9]+]], [x[[ADDR]], #8]
138 %0 = load <2 x i32>* %in, align 8
139 %call = tail call double @args_vec_2i(double 3.000000e+00, <2 x i32> %0,
140 <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0,
141 <2 x i32> %0, float 3.000000e+00, <2 x i32> %0, i8 signext 3)
142 ret double %call
143}
144declare double @args_vec_2i(double, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>,
145 <2 x i32>, <2 x i32>, <2 x i32>, float, <2 x i32>, i8 signext)
146
147define double @test4(double* nocapture %in) nounwind {
148entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000149; CHECK-LABEL: test4
Tim Northover00ed9962014-03-29 10:18:08 +0000150; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
151; CHECK: str [[REG_2:w[0-9]+]], [sp]
152; CHECK: orr w0, wzr, #0x3
153 %0 = load double* %in, align 8
154 %call = tail call double @args_f64(double 3.000000e+00, double %0, double %0,
155 double %0, double %0, double %0, double %0, double %0,
156 float 3.000000e+00, double %0, i8 signext 3)
157 ret double %call
158}
159declare double @args_f64(double, double, double, double, double, double, double,
160 double, float, double, i8 signext)
161
162define i64 @test5(i64* nocapture %in) nounwind {
163entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000164; CHECK-LABEL: test5
Tim Northover00ed9962014-03-29 10:18:08 +0000165; CHECK: strb [[REG_3:w[0-9]+]], [sp, #16]
166; CHECK: str [[REG_1:x[0-9]+]], [sp, #8]
167; CHECK: str [[REG_2:w[0-9]+]], [sp]
168 %0 = load i64* %in, align 8
169 %call = tail call i64 @args_i64(i64 3, i64 %0, i64 %0, i64 %0, i64 %0, i64 %0,
170 i64 %0, i64 %0, i32 3, i64 %0, i8 signext 3)
171 ret i64 %call
172}
173declare i64 @args_i64(i64, i64, i64, i64, i64, i64, i64, i64, i32, i64,
174 i8 signext)
175
176define i32 @test6(float* nocapture %in) nounwind {
177entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000178; CHECK-LABEL: test6
Tim Northover00ed9962014-03-29 10:18:08 +0000179; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
180; CHECK: str [[REG_1:s[0-9]+]], [sp, #4]
181; CHECK: strh [[REG_3:w[0-9]+]], [sp]
182 %0 = load float* %in, align 4
183 %call = tail call i32 @args_f32(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
184 i32 7, i32 8, float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
185 float 6.0, float 7.0, float 8.0, i16 signext 3, float %0,
186 i8 signext 3)
187 ret i32 %call
188}
189declare i32 @args_f32(i32, i32, i32, i32, i32, i32, i32, i32,
190 float, float, float, float, float, float, float, float,
191 i16 signext, float, i8 signext)
192
193define i32 @test7(i32* nocapture %in) nounwind {
194entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000195; CHECK-LABEL: test7
Tim Northover00ed9962014-03-29 10:18:08 +0000196; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
197; CHECK: str [[REG_1:w[0-9]+]], [sp, #4]
198; CHECK: strh [[REG_3:w[0-9]+]], [sp]
199 %0 = load i32* %in, align 4
200 %call = tail call i32 @args_i32(i32 3, i32 %0, i32 %0, i32 %0, i32 %0, i32 %0,
201 i32 %0, i32 %0, i16 signext 3, i32 %0, i8 signext 4)
202 ret i32 %call
203}
204declare i32 @args_i32(i32, i32, i32, i32, i32, i32, i32, i32, i16 signext, i32,
205 i8 signext)
206
207define i32 @test8(i32 %argc, i8** nocapture %argv) nounwind {
208entry:
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000209; CHECK-LABEL: test8
Tim Northover00ed9962014-03-29 10:18:08 +0000210; CHECK: strb {{w[0-9]+}}, [sp, #3]
211; CHECK: strb wzr, [sp, #2]
212; CHECK: strb {{w[0-9]+}}, [sp, #1]
213; CHECK: strb wzr, [sp]
214; CHECK: bl
Juergen Ributzka88f6faf2014-07-22 23:14:54 +0000215; FAST-LABEL: test8
Tim Northover00ed9962014-03-29 10:18:08 +0000216; FAST: strb {{w[0-9]+}}, [sp]
217; FAST: strb {{w[0-9]+}}, [sp, #1]
218; FAST: strb {{w[0-9]+}}, [sp, #2]
219; FAST: strb {{w[0-9]+}}, [sp, #3]
220; FAST: bl
221 tail call void @args_i1(i1 zeroext false, i1 zeroext true, i1 zeroext false,
222 i1 zeroext true, i1 zeroext false, i1 zeroext true,
223 i1 zeroext false, i1 zeroext true, i1 zeroext false,
224 i1 zeroext true, i1 zeroext false, i1 zeroext true)
225 ret i32 0
226}
227
228declare void @args_i1(i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
229 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
230 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext)
231
232define i32 @i1_stack_incoming(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f,
233 i64 %g, i64 %h, i64 %i, i1 zeroext %j) {
234; CHECK-LABEL: i1_stack_incoming:
235; CHECK: ldrb w0, [sp, #8]
236; CHECK: ret
237 %v = zext i1 %j to i32
238 ret i32 %v
239}