blob: a7693b6ba9e57440ec73d96d4bb5d57c3ed2c1d1 [file] [log] [blame]
Tim Northover00ed9962014-03-29 10:18:08 +00001; RUN: llc < %s -march=arm64 -mcpu=cyclone -enable-misched=false | FileCheck %s
2; RUN: llc < %s -O0 | FileCheck -check-prefix=FAST %s
3target triple = "arm64-apple-darwin"
4
5; rdar://9932559
6define 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 {
7entry:
8; CHECK-LABEL: i8i16callee:
9; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5.
10; They are i8, i16, i8 and i8.
11; CHECK: ldrsb {{w[0-9]+}}, [sp, #5]
12; CHECK: ldrsh {{w[0-9]+}}, [sp, #2]
13; CHECK: ldrsb {{w[0-9]+}}, [sp]
14; CHECK: ldrsb {{w[0-9]+}}, [sp, #4]
15; FAST-LABEL: i8i16callee:
16; FAST: ldrb {{w[0-9]+}}, [sp, #5]
17; FAST: ldrb {{w[0-9]+}}, [sp, #4]
18; FAST: ldrh {{w[0-9]+}}, [sp, #2]
19; FAST: ldrb {{w[0-9]+}}, [sp]
20 %conv = sext i8 %a4 to i64
21 %conv3 = sext i16 %a5 to i64
22 %conv8 = sext i8 %b1 to i64
23 %conv9 = sext i16 %b2 to i64
24 %conv11 = sext i8 %b3 to i64
25 %conv13 = sext i8 %b4 to i64
26 %add10 = add i64 %a2, %a1
27 %add12 = add i64 %add10, %a3
28 %add14 = add i64 %add12, %conv
29 %add = add i64 %add14, %conv3
30 %add1 = add i64 %add, %a6
31 %add2 = add i64 %add1, %a7
32 %add4 = add i64 %add2, %a8
33 %add5 = add i64 %add4, %conv8
34 %add6 = add i64 %add5, %conv9
35 %add7 = add i64 %add6, %conv11
36 %add15 = add i64 %add7, %conv13
37 %sext = shl i64 %add15, 32
38 %conv17 = ashr exact i64 %sext, 32
39 ret i64 %conv17
40}
41
42define i32 @i8i16caller() nounwind readnone {
43entry:
44; CHECK: i8i16caller
45; The 8th, 9th, 10th and 11th arguments are passed at sp, sp+2, sp+4, sp+5.
46; They are i8, i16, i8 and i8.
47; CHECK: strb {{w[0-9]+}}, [sp, #5]
48; CHECK: strb {{w[0-9]+}}, [sp, #4]
49; CHECK: strh {{w[0-9]+}}, [sp, #2]
50; CHECK: strb {{w[0-9]+}}, [sp]
51; CHECK: bl
52; FAST: i8i16caller
53; FAST: strb {{w[0-9]+}}, [sp]
54; FAST: strh {{w[0-9]+}}, [sp, #2]
55; FAST: strb {{w[0-9]+}}, [sp, #4]
56; FAST: strb {{w[0-9]+}}, [sp, #5]
57; FAST: bl
58 %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)
59 %conv = trunc i64 %call to i32
60 ret i32 %conv
61}
62
63; rdar://12651543
64define double @circle_center([2 x float] %a) nounwind ssp {
65 %call = tail call double @ext([2 x float] %a) nounwind
66; CHECK: circle_center
67; CHECK: bl
68 ret double %call
69}
70declare double @ext([2 x float])
71
72; rdar://12656141
73; 16-byte vector should be aligned at 16-byte when passing on stack.
74; A double argument will be passed on stack, so vecotr should be at sp+16.
75define double @fixed_4i(<4 x i32>* nocapture %in) nounwind {
76entry:
77; CHECK: fixed_4i
78; CHECK: str [[REG_1:q[0-9]+]], [sp, #16]
79; FAST: 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)
84 ret double %call
85}
86declare 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)
87
88; rdar://12695237
89; d8 at sp, i in register w0.
90@g_d = common global double 0.000000e+00, align 8
91define 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 {
93entry:
94; CHECK: test1
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
104 ret void
105}
106
107; i9 at sp, d1 in register s0.
108define 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 {
110entry:
111; CHECK: test2
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
123 ret void
124}
125
126; rdar://12648441
127; Check alignment on stack for v64, f64, i64, f32, i32.
128define double @test3(<2 x i32>* nocapture %in) nounwind {
129entry:
130; CHECK: test3
131; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
132; FAST: test3
133; FAST: mov x[[ADDR:[0-9]+]], sp
134; FAST: str [[REG_1:d[0-9]+]], [x[[ADDR]], #8]
135 %0 = load <2 x i32>* %in, align 8
136 %call = tail call double @args_vec_2i(double 3.000000e+00, <2 x i32> %0,
137 <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0,
138 <2 x i32> %0, float 3.000000e+00, <2 x i32> %0, i8 signext 3)
139 ret double %call
140}
141declare double @args_vec_2i(double, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>,
142 <2 x i32>, <2 x i32>, <2 x i32>, float, <2 x i32>, i8 signext)
143
144define double @test4(double* nocapture %in) nounwind {
145entry:
146; CHECK: test4
147; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
148; CHECK: str [[REG_2:w[0-9]+]], [sp]
149; CHECK: orr w0, wzr, #0x3
150 %0 = load double* %in, align 8
151 %call = tail call double @args_f64(double 3.000000e+00, double %0, double %0,
152 double %0, double %0, double %0, double %0, double %0,
153 float 3.000000e+00, double %0, i8 signext 3)
154 ret double %call
155}
156declare double @args_f64(double, double, double, double, double, double, double,
157 double, float, double, i8 signext)
158
159define i64 @test5(i64* nocapture %in) nounwind {
160entry:
161; CHECK: test5
162; CHECK: strb [[REG_3:w[0-9]+]], [sp, #16]
163; CHECK: str [[REG_1:x[0-9]+]], [sp, #8]
164; CHECK: str [[REG_2:w[0-9]+]], [sp]
165 %0 = load i64* %in, align 8
166 %call = tail call i64 @args_i64(i64 3, i64 %0, i64 %0, i64 %0, i64 %0, i64 %0,
167 i64 %0, i64 %0, i32 3, i64 %0, i8 signext 3)
168 ret i64 %call
169}
170declare i64 @args_i64(i64, i64, i64, i64, i64, i64, i64, i64, i32, i64,
171 i8 signext)
172
173define i32 @test6(float* nocapture %in) nounwind {
174entry:
175; CHECK: test6
176; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
177; CHECK: str [[REG_1:s[0-9]+]], [sp, #4]
178; CHECK: strh [[REG_3:w[0-9]+]], [sp]
179 %0 = load float* %in, align 4
180 %call = tail call i32 @args_f32(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
181 i32 7, i32 8, float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
182 float 6.0, float 7.0, float 8.0, i16 signext 3, float %0,
183 i8 signext 3)
184 ret i32 %call
185}
186declare i32 @args_f32(i32, i32, i32, i32, i32, i32, i32, i32,
187 float, float, float, float, float, float, float, float,
188 i16 signext, float, i8 signext)
189
190define i32 @test7(i32* nocapture %in) nounwind {
191entry:
192; CHECK: test7
193; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
194; CHECK: str [[REG_1:w[0-9]+]], [sp, #4]
195; CHECK: strh [[REG_3:w[0-9]+]], [sp]
196 %0 = load i32* %in, align 4
197 %call = tail call i32 @args_i32(i32 3, i32 %0, i32 %0, i32 %0, i32 %0, i32 %0,
198 i32 %0, i32 %0, i16 signext 3, i32 %0, i8 signext 4)
199 ret i32 %call
200}
201declare i32 @args_i32(i32, i32, i32, i32, i32, i32, i32, i32, i16 signext, i32,
202 i8 signext)
203
204define i32 @test8(i32 %argc, i8** nocapture %argv) nounwind {
205entry:
206; CHECK: test8
207; CHECK: strb {{w[0-9]+}}, [sp, #3]
208; CHECK: strb wzr, [sp, #2]
209; CHECK: strb {{w[0-9]+}}, [sp, #1]
210; CHECK: strb wzr, [sp]
211; CHECK: bl
212; FAST: test8
213; FAST: strb {{w[0-9]+}}, [sp]
214; FAST: strb {{w[0-9]+}}, [sp, #1]
215; FAST: strb {{w[0-9]+}}, [sp, #2]
216; FAST: strb {{w[0-9]+}}, [sp, #3]
217; FAST: bl
218 tail call void @args_i1(i1 zeroext false, i1 zeroext true, i1 zeroext false,
219 i1 zeroext true, i1 zeroext false, i1 zeroext true,
220 i1 zeroext false, i1 zeroext true, i1 zeroext false,
221 i1 zeroext true, i1 zeroext false, i1 zeroext true)
222 ret i32 0
223}
224
225declare void @args_i1(i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
226 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
227 i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext)
228
229define i32 @i1_stack_incoming(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f,
230 i64 %g, i64 %h, i64 %i, i1 zeroext %j) {
231; CHECK-LABEL: i1_stack_incoming:
232; CHECK: ldrb w0, [sp, #8]
233; CHECK: ret
234 %v = zext i1 %j to i32
235 ret i32 %v
236}