[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / arm64-abi.ll
blob1a44a000d302537af3b5f14b04ccde1fb67d5ef8
1 ; RUN: llc     -mtriple=arm64-apple-darwin -mcpu=cyclone -enable-misched=false < %s | FileCheck %s
2 ; RUN: llc -O0 -fast-isel -mtriple=arm64-apple-darwin                          < %s | FileCheck --check-prefix=FAST %s
4 ; rdar://9932559
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 {
6 entry:
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
38   ret i64 %conv17
41 define i32 @i8i16caller() nounwind readnone {
42 entry:
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: stur {{w[0-9]+}}, [sp, #2]
47 ; CHECK-DAG: strb {{w[0-9]+}}, [sp]
48 ; CHECK: bl
49 ; FAST-LABEL: i8i16caller
50 ; FAST: strb {{w[0-9]+}}, [sp]
51 ; FAST: strh {{w[0-9]+}}, [sp, #2]
52 ; FAST: strb {{w[0-9]+}}, [sp, #4]
53 ; FAST: strb {{w[0-9]+}}, [sp, #5]
54 ; FAST: bl
55   %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)
56   %conv = trunc i64 %call to i32
57   ret i32 %conv
60 ; rdar://12651543
61 define double @circle_center([2 x float] %a) nounwind ssp {
62   %call = tail call double @ext([2 x float] %a) nounwind
63 ; CHECK-LABEL: circle_center
64 ; CHECK: bl
65   ret double %call
67 declare double @ext([2 x float])
69 ; rdar://12656141
70 ; 16-byte vector should be aligned at 16-byte when passing on stack.
71 ; A double argument will be passed on stack, so vecotr should be at sp+16.
72 define double @fixed_4i(<4 x i32>* nocapture %in) nounwind {
73 entry:
74 ; CHECK-LABEL: fixed_4i
75 ; CHECK: str [[REG_1:q[0-9]+]], [sp, #16]
76 ; FAST-LABEL: fixed_4i
77 ; FAST: sub sp, sp
78 ; FAST: mov x[[ADDR:[0-9]+]], sp
79 ; FAST: str [[REG_1:q[0-9]+]], [x[[ADDR]], #16]
80   %0 = load <4 x i32>, <4 x i32>* %in, align 16
81   %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)
82   ret double %call
84 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)
86 ; rdar://12695237
87 ; d8 at sp, i in register w0.
88 @g_d = common global double 0.000000e+00, align 8
89 define void @test1(float %f1, double %d1, double %d2, double %d3, double %d4,
90        double %d5, double %d6, double %d7, double %d8, i32 %i) nounwind ssp {
91 entry:
92 ; CHECK-LABEL: test1
93 ; CHECK: ldr [[REG_1:d[0-9]+]], [sp]
94 ; CHECK: scvtf [[REG_2:s[0-9]+]], w0
95 ; CHECK: fadd s0, [[REG_2]], s0
96   %conv = sitofp i32 %i to float
97   %add = fadd float %conv, %f1
98   %conv1 = fpext float %add to double
99   %add2 = fadd double %conv1, %d7
100   %add3 = fadd double %add2, %d8
101   store double %add3, double* @g_d, align 8
102   ret void
105 ; i9 at sp, d1 in register s0.
106 define void @test2(i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
107             i32 %i7, i32 %i8, i32 %i9, float %d1) nounwind ssp {
108 entry:
109 ; CHECK-LABEL: test2
110 ; CHECK: scvtf [[REG_2:s[0-9]+]], w0
111 ; CHECK: fadd s0, [[REG_2]], s0
112 ; CHECK: ldr [[REG_1:s[0-9]+]], [sp]
113   %conv = sitofp i32 %i1 to float
114   %add = fadd float %conv, %d1
115   %conv1 = fpext float %add to double
116   %conv2 = sitofp i32 %i8 to double
117   %add3 = fadd double %conv2, %conv1
118   %conv4 = sitofp i32 %i9 to double
119   %add5 = fadd double %conv4, %add3
120   store double %add5, double* @g_d, align 8
121   ret void
124 ; rdar://12648441
125 ; Check alignment on stack for v64, f64, i64, f32, i32.
126 define double @test3(<2 x i32>* nocapture %in) nounwind {
127 entry:
128 ; CHECK-LABEL: test3
129 ; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
130 ; FAST-LABEL: test3
131 ; FAST: sub sp, sp, #{{[0-9]+}}
132 ; FAST: mov x[[ADDR:[0-9]+]], sp
133 ; FAST: str [[REG_1:d[0-9]+]], [x[[ADDR]], #8]
134   %0 = load <2 x i32>, <2 x i32>* %in, align 8
135   %call = tail call double @args_vec_2i(double 3.000000e+00, <2 x i32> %0,
136           <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0, <2 x i32> %0,
137           <2 x i32> %0, float 3.000000e+00, <2 x i32> %0, i8 signext 3)
138   ret double %call
140 declare double @args_vec_2i(double, <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>,
141                <2 x i32>, <2 x i32>, <2 x i32>, float, <2 x i32>, i8 signext)
143 define double @test4(double* nocapture %in) nounwind {
144 entry:
145 ; CHECK-LABEL: test4
146 ; CHECK: str [[REG_1:d[0-9]+]], [sp, #8]
147 ; CHECK: str [[REG_2:w[0-9]+]], [sp]
148 ; CHECK: mov w0, #3
149   %0 = load double, double* %in, align 8
150   %call = tail call double @args_f64(double 3.000000e+00, double %0, double %0,
151           double %0, double %0, double %0, double %0, double %0,
152           float 3.000000e+00, double %0, i8 signext 3)
153   ret double %call
155 declare double @args_f64(double, double, double, double, double, double, double,
156                double, float, double, i8 signext)
158 define i64 @test5(i64* nocapture %in) nounwind {
159 entry:
160 ; CHECK-LABEL: test5
161 ; CHECK: strb [[REG_3:w[0-9]+]], [sp, #16]
162 ; CHECK: str [[REG_1:x[0-9]+]], [sp, #8]
163 ; CHECK: str [[REG_2:w[0-9]+]], [sp]
164   %0 = load i64, i64* %in, align 8
165   %call = tail call i64 @args_i64(i64 3, i64 %0, i64 %0, i64 %0, i64 %0, i64 %0,
166                          i64 %0, i64 %0, i32 3, i64 %0, i8 signext 3)
167   ret i64 %call
169 declare i64 @args_i64(i64, i64, i64, i64, i64, i64, i64, i64, i32, i64,
170              i8 signext)
172 define i32 @test6(float* nocapture %in) nounwind {
173 entry:
174 ; CHECK-LABEL: test6
175 ; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
176 ; CHECK: str [[REG_1:s[0-9]+]], [sp, #4]
177 ; CHECK: strh [[REG_3:w[0-9]+]], [sp]
178   %0 = load float, float* %in, align 4
179   %call = tail call i32 @args_f32(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
180           i32 7, i32 8, float 1.0, float 2.0, float 3.0, float 4.0, float 5.0,
181           float 6.0, float 7.0, float 8.0, i16 signext 3, float %0,
182           i8 signext 3)
183   ret i32 %call
185 declare i32 @args_f32(i32, i32, i32, i32, i32, i32, i32, i32,
186                       float, float, float, float, float, float, float, float,
187                       i16 signext, float, i8 signext)
189 define i32 @test7(i32* nocapture %in) nounwind {
190 entry:
191 ; CHECK-LABEL: test7
192 ; CHECK: strb [[REG_2:w[0-9]+]], [sp, #8]
193 ; CHECK: str [[REG_1:w[0-9]+]], [sp, #4]
194 ; CHECK: strh [[REG_3:w[0-9]+]], [sp]
195   %0 = load i32, i32* %in, align 4
196   %call = tail call i32 @args_i32(i32 3, i32 %0, i32 %0, i32 %0, i32 %0, i32 %0,
197                          i32 %0, i32 %0, i16 signext 3, i32 %0, i8 signext 4)
198   ret i32 %call
200 declare i32 @args_i32(i32, i32, i32, i32, i32, i32, i32, i32, i16 signext, i32,
201              i8 signext)
203 define i32 @test8(i32 %argc, i8** nocapture %argv) nounwind {
204 entry:
205 ; CHECK-LABEL: test8
206 ; CHECK: str w8, [sp]
207 ; CHECK: bl
208 ; FAST-LABEL: test8
209 ; FAST: strb {{w[0-9]+}}, [sp]
210 ; FAST: strb {{w[0-9]+}}, [sp, #1]
211 ; FAST: strb {{w[0-9]+}}, [sp, #2]
212 ; FAST: strb {{w[0-9]+}}, [sp, #3]
213 ; FAST: bl
214   tail call void @args_i1(i1 zeroext false, i1 zeroext true, i1 zeroext false,
215                   i1 zeroext true, i1 zeroext false, i1 zeroext true,
216                   i1 zeroext false, i1 zeroext true, i1 zeroext false,
217                   i1 zeroext true, i1 zeroext false, i1 zeroext true)
218   ret i32 0
221 declare void @args_i1(i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
222                       i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext,
223                       i1 zeroext, i1 zeroext, i1 zeroext, i1 zeroext)
225 define i32 @i1_stack_incoming(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f,
226                                i64 %g, i64 %h, i64 %i, i1 zeroext %j) {
227 ; CHECK-LABEL: i1_stack_incoming:
228 ; CHECK: ldrb w0, [sp, #8]
229 ; CHECK: ret
230   %v = zext i1 %j to i32
231   ret i32 %v