xref: /llvm-project/mlir/test/Target/LLVMIR/arm-sve.mlir (revision 781133037387eefa4080aa31c73554cc0452e6e6)
1// RUN: mlir-translate --mlir-to-llvmir %s | FileCheck %s
2
3// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_sdot
4llvm.func @arm_sve_sdot(%arg0: vector<[16]xi8>,
5                        %arg1: vector<[16]xi8>,
6                        %arg2: vector<[4]xi32>)
7                        -> vector<[4]xi32> {
8  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.sdot.nxv4i32(<vscale x 4
9  %0 = "arm_sve.intr.sdot"(%arg2, %arg0, %arg1) :
10    (vector<[4]xi32>, vector<[16]xi8>, vector<[16]xi8>)
11        -> vector<[4]xi32>
12  llvm.return %0 : vector<[4]xi32>
13}
14
15// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_smmla
16llvm.func @arm_sve_smmla(%arg0: vector<[16]xi8>,
17                         %arg1: vector<[16]xi8>,
18                         %arg2: vector<[4]xi32>)
19                         -> vector<[4]xi32> {
20  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.smmla.nxv4i32(<vscale x 4
21  %0 = "arm_sve.intr.smmla"(%arg2, %arg0, %arg1) :
22    (vector<[4]xi32>, vector<[16]xi8>, vector<[16]xi8>)
23        -> vector<[4]xi32>
24  llvm.return %0 : vector<[4]xi32>
25}
26
27// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_udot
28llvm.func @arm_sve_udot(%arg0: vector<[16]xi8>,
29                        %arg1: vector<[16]xi8>,
30                        %arg2: vector<[4]xi32>)
31                        -> vector<[4]xi32> {
32  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.udot.nxv4i32(<vscale x 4
33  %0 = "arm_sve.intr.udot"(%arg2, %arg0, %arg1) :
34    (vector<[4]xi32>, vector<[16]xi8>, vector<[16]xi8>)
35        -> vector<[4]xi32>
36  llvm.return %0 : vector<[4]xi32>
37}
38
39// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_ummla
40llvm.func @arm_sve_ummla(%arg0: vector<[16]xi8>,
41                         %arg1: vector<[16]xi8>,
42                         %arg2: vector<[4]xi32>)
43                         -> vector<[4]xi32> {
44  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.ummla.nxv4i32(<vscale x 4
45  %0 = "arm_sve.intr.ummla"(%arg2, %arg0, %arg1) :
46    (vector<[4]xi32>, vector<[16]xi8>, vector<[16]xi8>)
47        -> vector<[4]xi32>
48  llvm.return %0 : vector<[4]xi32>
49}
50
51// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_arithi
52llvm.func @arm_sve_arithi(%arg0: vector<[4]xi32>,
53                          %arg1: vector<[4]xi32>,
54                          %arg2: vector<[4]xi32>)
55                          -> vector<[4]xi32> {
56  // CHECK: mul <vscale x 4 x i32>
57  %0 = llvm.mul %arg0, %arg1 : vector<[4]xi32>
58  // CHECK: add <vscale x 4 x i32>
59  %1 = llvm.add %0, %arg2 : vector<[4]xi32>
60  llvm.return %1 : vector<[4]xi32>
61}
62
63// CHECK-LABEL: define <vscale x 4 x float> @arm_sve_arithf
64llvm.func @arm_sve_arithf(%arg0: vector<[4]xf32>,
65                          %arg1: vector<[4]xf32>,
66                          %arg2: vector<[4]xf32>)
67                          -> vector<[4]xf32> {
68  // CHECK: fmul <vscale x 4 x float>
69  %0 = llvm.fmul %arg0, %arg1 : vector<[4]xf32>
70  // CHECK: fadd <vscale x 4 x float>
71  %1 = llvm.fadd %0, %arg2 : vector<[4]xf32>
72  llvm.return %1 : vector<[4]xf32>
73}
74
75// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_arithi_masked
76llvm.func @arm_sve_arithi_masked(%arg0: vector<[4]xi32>,
77                                 %arg1: vector<[4]xi32>,
78                                 %arg2: vector<[4]xi32>,
79                                 %arg3: vector<[4]xi32>,
80                                 %arg4: vector<[4]xi32>,
81                                 %arg5: vector<[4]xi1>)
82                                 -> vector<[4]xi32> {
83  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.add.nxv4i32
84  %0 = "arm_sve.intr.add"(%arg5, %arg0, %arg1) : (vector<[4]xi1>,
85                                                  vector<[4]xi32>,
86                                                  vector<[4]xi32>)
87                                                  -> vector<[4]xi32>
88  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.sub.nxv4i32
89  %1 = "arm_sve.intr.sub"(%arg5, %0, %arg1) : (vector<[4]xi1>,
90                                               vector<[4]xi32>,
91                                               vector<[4]xi32>)
92                                               -> vector<[4]xi32>
93  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.mul.nxv4i32
94  %2 = "arm_sve.intr.mul"(%arg5, %1, %arg3) : (vector<[4]xi1>,
95                                               vector<[4]xi32>,
96                                               vector<[4]xi32>)
97                                               -> vector<[4]xi32>
98  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.sdiv.nxv4i32
99  %3 = "arm_sve.intr.sdiv"(%arg5, %2, %arg4) : (vector<[4]xi1>,
100                                               vector<[4]xi32>,
101                                               vector<[4]xi32>)
102                                               -> vector<[4]xi32>
103  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.udiv.nxv4i32
104  %4 = "arm_sve.intr.udiv"(%arg5, %3, %arg4) : (vector<[4]xi1>,
105                                               vector<[4]xi32>,
106                                               vector<[4]xi32>)
107                                               -> vector<[4]xi32>
108  llvm.return %4 : vector<[4]xi32>
109}
110
111// CHECK-LABEL: define <vscale x 4 x float> @arm_sve_arithf_masked
112llvm.func @arm_sve_arithf_masked(%arg0: vector<[4]xf32>,
113                                 %arg1: vector<[4]xf32>,
114                                 %arg2: vector<[4]xf32>,
115                                 %arg3: vector<[4]xf32>,
116                                 %arg4: vector<[4]xf32>,
117                                 %arg5: vector<[4]xi1>)
118                                 -> vector<[4]xf32> {
119  // CHECK: call <vscale x 4 x float> @llvm.aarch64.sve.fadd.nxv4f32
120  %0 = "arm_sve.intr.fadd"(%arg5, %arg0, %arg1) : (vector<[4]xi1>,
121                                                   vector<[4]xf32>,
122                                                   vector<[4]xf32>)
123                                                   -> vector<[4]xf32>
124  // CHECK: call <vscale x 4 x float> @llvm.aarch64.sve.fsub.nxv4f32
125  %1 = "arm_sve.intr.fsub"(%arg5, %0, %arg2) : (vector<[4]xi1>,
126                                                vector<[4]xf32>,
127                                                vector<[4]xf32>)
128                                                -> vector<[4]xf32>
129  // CHECK: call <vscale x 4 x float> @llvm.aarch64.sve.fmul.nxv4f32
130  %2 = "arm_sve.intr.fmul"(%arg5, %1, %arg3) : (vector<[4]xi1>,
131                                                vector<[4]xf32>,
132                                                vector<[4]xf32>)
133                                                -> vector<[4]xf32>
134  // CHECK: call <vscale x 4 x float> @llvm.aarch64.sve.fdiv.nxv4f32
135  %3 = "arm_sve.intr.fdiv"(%arg5, %2, %arg4) : (vector<[4]xi1>,
136                                                vector<[4]xf32>,
137                                                vector<[4]xf32>)
138                                                -> vector<[4]xf32>
139  llvm.return %3 : vector<[4]xf32>
140}
141
142// CHECK-LABEL: define <vscale x 4 x i1> @arm_sve_mask_genf
143llvm.func @arm_sve_mask_genf(%arg0: vector<[4]xf32>,
144                             %arg1: vector<[4]xf32>)
145                             -> vector<[4]xi1> {
146  // CHECK: fcmp oeq <vscale x 4 x float>
147  %0 = llvm.fcmp "oeq" %arg0, %arg1 : vector<[4]xf32>
148  llvm.return %0 : vector<[4]xi1>
149}
150
151// CHECK-LABEL: define <vscale x 4 x i1> @arm_sve_mask_geni
152llvm.func @arm_sve_mask_geni(%arg0: vector<[4]xi32>,
153                             %arg1: vector<[4]xi32>)
154                             -> vector<[4]xi1> {
155  // CHECK: icmp uge <vscale x 4 x i32>
156  %0 = llvm.icmp "uge" %arg0, %arg1 : vector<[4]xi32>
157  llvm.return %0 : vector<[4]xi1>
158}
159
160// CHECK-LABEL: define <vscale x 4 x i32> @arm_sve_abs_diff
161llvm.func @arm_sve_abs_diff(%arg0: vector<[4]xi32>,
162                            %arg1: vector<[4]xi32>)
163                            -> vector<[4]xi32> {
164  // CHECK: sub <vscale x 4 x i32>
165  %0 = llvm.sub %arg0, %arg0  : vector<[4]xi32>
166  // CHECK: icmp sge <vscale x 4 x i32>
167  %1 = llvm.icmp "sge" %arg0, %arg1 : vector<[4]xi32>
168  // CHECK: icmp slt <vscale x 4 x i32>
169  %2 = llvm.icmp "slt" %arg0, %arg1 : vector<[4]xi32>
170  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.sub.nxv4i32
171  %3 = "arm_sve.intr.sub"(%1, %arg0, %arg1) : (vector<[4]xi1>,
172                                               vector<[4]xi32>,
173                                               vector<[4]xi32>)
174                                               -> vector<[4]xi32>
175  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.sub.nxv4i32
176  %4 = "arm_sve.intr.sub"(%2, %arg1, %arg0) : (vector<[4]xi1>,
177                                               vector<[4]xi32>,
178                                               vector<[4]xi32>)
179                                               -> vector<[4]xi32>
180  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.add.nxv4i32
181  %5 = "arm_sve.intr.add"(%1, %0, %3) : (vector<[4]xi1>,
182                                         vector<[4]xi32>,
183                                         vector<[4]xi32>)
184                                         -> vector<[4]xi32>
185  // CHECK: call <vscale x 4 x i32> @llvm.aarch64.sve.add.nxv4i32
186  %6 = "arm_sve.intr.add"(%2, %5, %4) : (vector<[4]xi1>,
187                                         vector<[4]xi32>,
188                                         vector<[4]xi32>)
189                                         -> vector<[4]xi32>
190  llvm.return %6 : vector<[4]xi32>
191}
192
193// CHECK-LABEL: define void @memcopy
194llvm.func @memcopy(%arg0: !llvm.ptr, %arg1: !llvm.ptr,
195                   %arg2: i64, %arg3: i64, %arg4: i64,
196                   %arg5: !llvm.ptr, %arg6: !llvm.ptr,
197                   %arg7: i64, %arg8: i64, %arg9: i64,
198                   %arg10: i64) {
199  %0 = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64,
200                                       array<1 x i64>, array<1 x i64>)>
201  %1 = llvm.insertvalue %arg0, %0[0] : !llvm.struct<(ptr, ptr, i64,
202                                                     array<1 x i64>,
203                                                     array<1 x i64>)>
204  %2 = llvm.insertvalue %arg1, %1[1] : !llvm.struct<(ptr, ptr, i64,
205                                                     array<1 x i64>,
206                                                     array<1 x i64>)>
207  %3 = llvm.insertvalue %arg2, %2[2] : !llvm.struct<(ptr, ptr, i64,
208                                                     array<1 x i64>,
209                                                     array<1 x i64>)>
210  %4 = llvm.insertvalue %arg3, %3[3, 0] : !llvm.struct<(ptr, ptr, i64,
211                                                        array<1 x i64>,
212                                                        array<1 x i64>)>
213  %5 = llvm.insertvalue %arg4, %4[4, 0] : !llvm.struct<(ptr, ptr, i64,
214                                                        array<1 x i64>,
215                                                        array<1 x i64>)>
216  %6 = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64,
217                                       array<1 x i64>,
218                                       array<1 x i64>)>
219  %7 = llvm.insertvalue %arg5, %6[0] : !llvm.struct<(ptr, ptr, i64,
220                                                     array<1 x i64>,
221                                                     array<1 x i64>)>
222  %8 = llvm.insertvalue %arg6, %7[1] : !llvm.struct<(ptr, ptr, i64,
223                                                     array<1 x i64>,
224                                                     array<1 x i64>)>
225  %9 = llvm.insertvalue %arg7, %8[2] : !llvm.struct<(ptr, ptr, i64,
226                                                     array<1 x i64>,
227                                                     array<1 x i64>)>
228  %10 = llvm.insertvalue %arg8, %9[3, 0] : !llvm.struct<(ptr, ptr, i64,
229                                                         array<1 x i64>,
230                                                         array<1 x i64>)>
231  %11 = llvm.insertvalue %arg9, %10[4, 0] : !llvm.struct<(ptr, ptr, i64,
232                                                         array<1 x i64>,
233                                                         array<1 x i64>)>
234  %12 = llvm.mlir.constant(0 : index) : i64
235  %13 = llvm.mlir.constant(4 : index) : i64
236  // CHECK: [[VL:%[0-9]+]] = call i64 @llvm.vscale.i64()
237  %14 = "llvm.intr.vscale"() : () -> i64
238  // CHECK: mul i64 [[VL]], 4
239  %15 = llvm.mul %14, %13  : i64
240  llvm.br ^bb1(%12 : i64)
241^bb1(%16: i64):
242  %17 = llvm.icmp "slt" %16, %arg10 : i64
243  llvm.cond_br %17, ^bb2, ^bb3
244^bb2:
245  // CHECK: extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] }
246  %18 = llvm.extractvalue %5[1] : !llvm.struct<(ptr, ptr, i64,
247                                                array<1 x i64>,
248                                                array<1 x i64>)>
249  // CHECK: getelementptr float, ptr
250  %19 = llvm.getelementptr %18[%16] : (!llvm.ptr, i64) -> !llvm.ptr, f32
251  // CHECK: load <vscale x 4 x float>, ptr
252  %21 = llvm.load %19 : !llvm.ptr -> vector<[4]xf32>
253  // CHECK: extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] }
254  %22 = llvm.extractvalue %11[1] : !llvm.struct<(ptr, ptr, i64,
255                                                 array<1 x i64>,
256                                                 array<1 x i64>)>
257  // CHECK: getelementptr float, ptr
258  %23 = llvm.getelementptr %22[%16] : (!llvm.ptr, i64) -> !llvm.ptr, f32
259  // CHECK: store <vscale x 4 x float> %{{[0-9]+}}, ptr %{{[0-9]+}}
260  llvm.store %21, %23 : vector<[4]xf32>, !llvm.ptr
261  %25 = llvm.add %16, %15  : i64
262  llvm.br ^bb1(%25 : i64)
263^bb3:
264  llvm.return
265}
266
267// CHECK-LABEL: define i64 @get_vector_scale()
268llvm.func @get_vector_scale() -> i64 {
269  // CHECK: call i64 @llvm.vscale.i64()
270  %0 = "llvm.intr.vscale"() : () -> i64
271  llvm.return %0 : i64
272}
273
274// CHECK-LABEL: @arm_sve_convert_from_svbool(
275// CHECK-SAME:                               <vscale x 16 x i1> %[[SVBOOL:[0-9]+]])
276llvm.func @arm_sve_convert_from_svbool(%nxv16i1 : vector<[16]xi1>) {
277  // CHECK: %[[RES0:.*]] = call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> %[[SVBOOL]])
278  %res0 = "arm_sve.intr.convert.from.svbool"(%nxv16i1)
279    : (vector<[16]xi1>) -> vector<[8]xi1>
280  // CHECK: %[[RES1:.*]] = call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> %[[SVBOOL]])
281  %res1 = "arm_sve.intr.convert.from.svbool"(%nxv16i1)
282    : (vector<[16]xi1>) -> vector<[4]xi1>
283  // CHECK: %[[RES2:.*]] = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %[[SVBOOL]])
284  %res2 = "arm_sve.intr.convert.from.svbool"(%nxv16i1)
285    : (vector<[16]xi1>) -> vector<[2]xi1>
286  // CHECK: %[[RES3:.*]] = call <vscale x 1 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv1i1(<vscale x 16 x i1> %[[SVBOOL]])
287  %res3 = "arm_sve.intr.convert.from.svbool"(%nxv16i1)
288    : (vector<[16]xi1>) -> vector<[1]xi1>
289  llvm.return
290}
291
292// CHECK-LABEL: arm_sve_convert_to_svbool(
293// CHECK-SAME:                            <vscale x 8 x i1> %[[P8:[0-9]+]],
294// CHECK-SAME:                            <vscale x 4 x i1> %[[P4:[0-9]+]],
295// CHECK-SAME:                            <vscale x 2 x i1> %[[P2:[0-9]+]],
296// CHECK-SAME:                            <vscale x 1 x i1> %[[P1:[0-9]+]])
297llvm.func @arm_sve_convert_to_svbool(
298                                       %nxv8i1  : vector<[8]xi1>,
299                                       %nxv4i1  : vector<[4]xi1>,
300                                       %nxv2i1  : vector<[2]xi1>,
301                                       %nxv1i1  : vector<[1]xi1>
302) {
303  // CHECK-NEXT: %[[RES0:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> %[[P8]])
304  %res0 = "arm_sve.intr.convert.to.svbool"(%nxv8i1)
305    : (vector<[8]xi1>) -> vector<[16]xi1>
306  // CHECK-NEXT: %[[RES1:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1> %[[P4]])
307  %res1 = "arm_sve.intr.convert.to.svbool"(%nxv4i1)
308    : (vector<[4]xi1>) -> vector<[16]xi1>
309  // CHECK-NEXT: %[[RES2:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv2i1(<vscale x 2 x i1> %[[P2]])
310  %res2 = "arm_sve.intr.convert.to.svbool"(%nxv2i1)
311    : (vector<[2]xi1>) -> vector<[16]xi1>
312  // CHECK-NEXT: %[[RES3:.*]] = call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv1i1(<vscale x 1 x i1> %[[P1]])
313  %res3 = "arm_sve.intr.convert.to.svbool"(%nxv1i1)
314    : (vector<[1]xi1>) -> vector<[16]xi1>
315  llvm.return
316}
317
318// CHECK-LABEL: arm_sve_zip_x2(
319// CHECK-SAME:                 <vscale x 16 x i8> %[[V1:[0-9]+]],
320// CHECK-SAME:                 <vscale x 8 x i16> %[[V2:[0-9]+]],
321// CHECK-SAME:                 <vscale x 4 x i32> %[[V3:[0-9]+]],
322// CHECK-SAME:                 <vscale x 2 x i64> %[[V4:[0-9]+]])
323llvm.func @arm_sve_zip_x2(%nxv16i8: vector<[16]xi8>, %nxv8i16: vector<[8]xi16>, %nxv4i32: vector<[4]xi32>, %nxv2i64: vector<[2]xi64>) {
324  // CHECK: call { <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.zip.x2.nxv16i8(<vscale x 16 x i8> %[[V1]], <vscale x 16 x i8> %[[V1]])
325  %0 = "arm_sve.intr.zip.x2"(%nxv16i8, %nxv16i8) : (vector<[16]xi8>, vector<[16]xi8>)
326    -> !llvm.struct<(vector<[16]xi8>, vector<[16]xi8>)>
327  // CHECK: call { <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.zip.x2.nxv8i16(<vscale x 8 x i16> %[[V2]], <vscale x 8 x i16> %[[V2]])
328  %1 = "arm_sve.intr.zip.x2"(%nxv8i16, %nxv8i16) : (vector<[8]xi16>, vector<[8]xi16>)
329    -> !llvm.struct<(vector<[8]xi16>, vector<[8]xi16>)>
330  // CHECK: call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.zip.x2.nxv4i32(<vscale x 4 x i32> %[[V3]], <vscale x 4 x i32> %[[V3]])
331  %2 = "arm_sve.intr.zip.x2"(%nxv4i32, %nxv4i32) : (vector<[4]xi32>, vector<[4]xi32>)
332    -> !llvm.struct<(vector<[4]xi32>, vector<[4]xi32>)>
333  // CHECK: call { <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.zip.x2.nxv2i64(<vscale x 2 x i64> %[[V4]], <vscale x 2 x i64> %[[V4]])
334  %3 = "arm_sve.intr.zip.x2"(%nxv2i64, %nxv2i64) : (vector<[2]xi64>, vector<[2]xi64>)
335     -> !llvm.struct<(vector<[2]xi64>, vector<[2]xi64>)>
336  llvm.return
337}
338
339// CHECK-LABEL: arm_sve_zip_x4(
340// CHECK-SAME:                 <vscale x 16 x i8> %[[V1:[0-9]+]],
341// CHECK-SAME:                 <vscale x 8 x i16> %[[V2:[0-9]+]],
342// CHECK-SAME:                 <vscale x 4 x i32> %[[V3:[0-9]+]],
343// CHECK-SAME:                 <vscale x 2 x i64> %[[V4:[0-9]+]])
344llvm.func @arm_sve_zip_x4(%nxv16i8: vector<[16]xi8>, %nxv8i16: vector<[8]xi16>, %nxv4i32: vector<[4]xi32>, %nxv2i64: vector<[2]xi64>) {
345  // CHECK: call { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } @llvm.aarch64.sve.zip.x4.nxv16i8(<vscale x 16 x i8> %[[V1]], <vscale x 16 x i8> %[[V1]], <vscale x 16 x i8> %[[V1]], <vscale x 16 x i8> %[[V1]])
346  %0 = "arm_sve.intr.zip.x4"(%nxv16i8, %nxv16i8, %nxv16i8, %nxv16i8) : (vector<[16]xi8>, vector<[16]xi8>, vector<[16]xi8>, vector<[16]xi8>)
347    -> !llvm.struct<(vector<[16]xi8>, vector<[16]xi8>, vector<[16]xi8>, vector<[16]xi8>)>
348  // CHECK: call { <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16> } @llvm.aarch64.sve.zip.x4.nxv8i16(<vscale x 8 x i16> %[[V2]], <vscale x 8 x i16> %[[V2]], <vscale x 8 x i16> %[[V2]], <vscale x 8 x i16> %[[V2]])
349  %1 = "arm_sve.intr.zip.x4"(%nxv8i16, %nxv8i16, %nxv8i16, %nxv8i16) : (vector<[8]xi16>, vector<[8]xi16>, vector<[8]xi16>, vector<[8]xi16>)
350    -> !llvm.struct<(vector<[8]xi16>, vector<[8]xi16>, vector<[8]xi16>, vector<[8]xi16>)>
351  // CHECK: call { <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.aarch64.sve.zip.x4.nxv4i32(<vscale x 4 x i32> %[[V3]], <vscale x 4 x i32> %[[V3]], <vscale x 4 x i32> %[[V3]], <vscale x 4 x i32> %[[V3]])
352  %2 = "arm_sve.intr.zip.x4"(%nxv4i32, %nxv4i32, %nxv4i32, %nxv4i32) : (vector<[4]xi32>, vector<[4]xi32>, vector<[4]xi32>, vector<[4]xi32>)
353    -> !llvm.struct<(vector<[4]xi32>, vector<[4]xi32>, vector<[4]xi32>, vector<[4]xi32>)>
354  // CHECK: call { <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64>, <vscale x 2 x i64> } @llvm.aarch64.sve.zip.x4.nxv2i64(<vscale x 2 x i64> %[[V4]], <vscale x 2 x i64> %[[V4]], <vscale x 2 x i64> %[[V4]], <vscale x 2 x i64> %[[V4]])
355  %3 = "arm_sve.intr.zip.x4"(%nxv2i64, %nxv2i64, %nxv2i64, %nxv2i64) : (vector<[2]xi64>, vector<[2]xi64>, vector<[2]xi64>, vector<[2]xi64>)
356     -> !llvm.struct<(vector<[2]xi64>, vector<[2]xi64>, vector<[2]xi64>, vector<[2]xi64>)>
357  llvm.return
358}
359
360// CHECK-LABEL: arm_sve_whilelt(
361// CHECK-SAME:                  i64 %[[BASE:[0-9]+]],
362// CHECK-SAME:                  i64 %[[N:[0-9]+]]
363llvm.func @arm_sve_whilelt(%base: i64, %n: i64) {
364  // call <vscale x 2 x i1> @llvm.aarch64.sve.whilelt.nxv2i1.i64(i64 %[[BASE]], i64 %[[N]])
365  %1 = "arm_sve.intr.whilelt"(%base, %n) : (i64, i64) -> vector<[2]xi1>
366  // call <vscale x 4 x i1> @llvm.aarch64.sve.whilelt.nxv4i1.i64(i64 %[[BASE]], i64 %[[N]])
367  %2 = "arm_sve.intr.whilelt"(%base, %n) : (i64, i64) -> vector<[4]xi1>
368  // call <vscale x 8 x i1> @llvm.aarch64.sve.whilelt.nxv8i1.i64(i64 %[[BASE]], i64 %[[N]])
369  %3 = "arm_sve.intr.whilelt"(%base, %n) : (i64, i64) -> vector<[8]xi1>
370  // call <vscale x 16 x i1> @llvm.aarch64.sve.whilelt.nxv16i1.i64(i64 %[[BASE]], i64 %[[N]])
371  %4 = "arm_sve.intr.whilelt"(%base, %n) : (i64, i64) -> vector<[16]xi1>
372  llvm.return
373}
374
375// CHECK-LABEL: arm_sve_psel(
376// CHECK-SAME:               <vscale x 16 x i1> %[[PN:[0-9]+]],
377// CHECK-SAME:               <vscale x 2 x i1> %[[P1:[0-9]+]],
378// CHECK-SAME:               <vscale x 4 x i1> %[[P2:[0-9]+]],
379// CHECK-SAME:               <vscale x 8 x i1> %[[P3:[0-9]+]],
380// CHECK-SAME:               <vscale x 16 x i1> %[[P4:[0-9]+]],
381// CHECK-SAME:               i32 %[[INDEX:[0-9]+]])
382llvm.func @arm_sve_psel(%pn: vector<[16]xi1>, %p1: vector<[2]xi1>, %p2: vector<[4]xi1>, %p3: vector<[8]xi1>, %p4: vector<[16]xi1>, %index: i32) {
383  // CHECK: call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv2i1(<vscale x 16 x i1> %[[PN]], <vscale x 2 x i1> %[[P1]], i32 %[[INDEX]])
384  "arm_sve.intr.psel"(%pn, %p1, %index) : (vector<[16]xi1>, vector<[2]xi1>, i32) -> vector<[16]xi1>
385  // CHECK: call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv4i1(<vscale x 16 x i1> %[[PN]], <vscale x 4 x i1> %[[P2]], i32 %[[INDEX]])
386  "arm_sve.intr.psel"(%pn, %p2, %index) : (vector<[16]xi1>, vector<[4]xi1>, i32) -> vector<[16]xi1>
387  // CHECK: call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv8i1(<vscale x 16 x i1> %[[PN]], <vscale x 8 x i1> %[[P3]], i32 %[[INDEX]])
388  "arm_sve.intr.psel"(%pn, %p3, %index) : (vector<[16]xi1>, vector<[8]xi1>, i32) -> vector<[16]xi1>
389  // CHECK: call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv16i1(<vscale x 16 x i1> %[[PN]], <vscale x 16 x i1> %[[P4]], i32 %[[INDEX]])
390  "arm_sve.intr.psel"(%pn, %p4, %index) : (vector<[16]xi1>, vector<[16]xi1>, i32) -> vector<[16]xi1>
391  llvm.return
392}
393