xref: /llvm-project/mlir/test/Conversion/ArmSMEToLLVM/arm-sme-to-llvm.mlir (revision c42512436b23ab50e7637f239abe8371407104a1)
1// RUN: mlir-opt %s --pass-pipeline="builtin.module(func.func(convert-arm-sme-to-llvm,cse,canonicalize))" -split-input-file | FileCheck %s
2// Test conversion of ArmSME ops to LLVM intrinsics.
3
4//===----------------------------------------------------------------------===//
5// arm_sme.load_tile_slice
6//===----------------------------------------------------------------------===//
7
8// CHECK-LABEL:   func.func @arm_sme_load_tile_slice_hor_i8(
9// CHECK-SAME:                                              %[[SRC:.*]]: memref<?x?xi8>,
10// CHECK-SAME:                                              %[[MASK:.*]]: vector<[16]xi1>,
11// CHECK-SAME:                                              %[[TILE_SLICE_INDEX:.*]]: index)
12// CHECK:           %[[C0:.*]] = arith.constant 0 : index
13// CHECK:           %[[MEM_DESC:.*]] = builtin.unrealized_conversion_cast %[[SRC]] : memref<?x?xi8> to !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
14// CHECK:           %[[C0_I64:.*]] = builtin.unrealized_conversion_cast %[[C0]] : index to i64
15// CHECK:           %[[ALIGNED_BASE:.*]] = llvm.extractvalue %[[MEM_DESC]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
16// CHECK:           %[[STRIDE:.*]] = llvm.extractvalue %[[MEM_DESC]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
17// CHECK:           %[[OFFSET:.*]] = llvm.mul %[[C0_I64]], %[[STRIDE]]  : i64
18// CHECK:           %[[GEP:.*]] = llvm.getelementptr %[[ALIGNED_BASE]]{{\[}}%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
19// CHECK:           %[[TILE_SLICE_INDEX_I32:.*]] = arith.index_castui %[[TILE_SLICE_INDEX]] : index to i32
20// CHECK:           "arm_sme.intr.ld1b.horiz"(%[[MASK]], %[[GEP]], %[[TILE_SLICE_INDEX_I32]]) <{tile_id = 0 : i32}> : (vector<[16]xi1>, !llvm.ptr, i32) -> ()
21// CHECK:           return
22// CHECK:         }
23func.func @arm_sme_load_tile_slice_hor_i8(%src : memref<?x?xi8>, %mask : vector<[16]xi1>, %tile_slice_index : index) {
24  %c0 = arith.constant 0 : index
25  %tile = arm_sme.get_tile : vector<[16]x[16]xi8>
26  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xi8>, vector<[16]xi1>, vector<[16]x[16]xi8>
27  "test.some_use" (%tile_update) : (vector<[16]x[16]xi8>) -> ()
28  return
29}
30
31// -----
32
33// CHECK-LABEL: @arm_sme_load_tile_slice_hor_i16
34// CHECK: "arm_sme.intr.ld1h.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
35func.func @arm_sme_load_tile_slice_hor_i16(%src : memref<?x?xi16>, %mask : vector<[8]xi1>, %tile_slice_index : index) {
36  %c0 = arith.constant 0 : index
37  %tile = arm_sme.get_tile : vector<[8]x[8]xi16>
38  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xi16>, vector<[8]xi1>, vector<[8]x[8]xi16>
39  "test.some_use" (%tile_update) : (vector<[8]x[8]xi16>) -> ()
40  return
41}
42
43// -----
44
45// CHECK-LABEL: @arm_sme_load_tile_slice_hor_i32
46// CHECK: "arm_sme.intr.ld1w.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
47func.func @arm_sme_load_tile_slice_hor_i32(%src : memref<?x?xi32>, %mask : vector<[4]xi1>, %tile_slice_index : index) {
48  %c0 = arith.constant 0 : index
49  %tile = arm_sme.get_tile : vector<[4]x[4]xi32>
50  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xi32>, vector<[4]xi1>, vector<[4]x[4]xi32>
51  "test.some_use" (%tile_update) : (vector<[4]x[4]xi32>) -> ()
52  return
53}
54
55// -----
56
57// CHECK-LABEL: @arm_sme_load_tile_slice_hor_i64
58// CHECK: "arm_sme.intr.ld1d.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
59func.func @arm_sme_load_tile_slice_hor_i64(%src : memref<?x?xi64>, %mask : vector<[2]xi1>, %tile_slice_index : index) {
60  %c0 = arith.constant 0 : index
61  %tile = arm_sme.get_tile : vector<[2]x[2]xi64>
62  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xi64>, vector<[2]xi1>, vector<[2]x[2]xi64>
63  "test.some_use" (%tile_update) : (vector<[2]x[2]xi64>) -> ()
64  return
65}
66
67// -----
68
69// CHECK-LABEL: @arm_sme_load_tile_slice_hor_i128
70// CHECK: "arm_sme.intr.ld1q.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[1]xi1>, !llvm.ptr, i32) -> ()
71func.func @arm_sme_load_tile_slice_hor_i128(%src : memref<?x?xi128>, %mask : vector<[1]xi1>, %tile_slice_index : index) {
72  %c0 = arith.constant 0 : index
73  %tile = arm_sme.get_tile : vector<[1]x[1]xi128>
74  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xi128>, vector<[1]xi1>, vector<[1]x[1]xi128>
75  "test.some_use" (%tile_update) : (vector<[1]x[1]xi128>) -> ()
76  return
77}
78
79// -----
80
81// CHECK-LABEL: @arm_sme_load_tile_slice_hor_f16
82// CHECK: "arm_sme.intr.ld1h.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
83func.func @arm_sme_load_tile_slice_hor_f16(%src : memref<?x?xf16>, %mask : vector<[8]xi1>, %tile_slice_index : index) {
84  %c0 = arith.constant 0 : index
85  %tile = arm_sme.get_tile : vector<[8]x[8]xf16>
86  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xf16>, vector<[8]xi1>, vector<[8]x[8]xf16>
87  "test.some_use" (%tile_update) : (vector<[8]x[8]xf16>) -> ()
88  return
89}
90
91// -----
92
93// CHECK-LABEL: @arm_sme_load_tile_slice_hor_bf16
94// CHECK: "arm_sme.intr.ld1h.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
95func.func @arm_sme_load_tile_slice_hor_bf16(%src : memref<?x?xbf16>, %mask : vector<[8]xi1>, %tile_slice_index : index) {
96  %c0 = arith.constant 0 : index
97  %tile = arm_sme.get_tile : vector<[8]x[8]xbf16>
98  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xbf16>, vector<[8]xi1>, vector<[8]x[8]xbf16>
99  "test.some_use" (%tile_update) : (vector<[8]x[8]xbf16>) -> ()
100  return
101}
102
103// -----
104
105// CHECK-LABEL: @arm_sme_load_tile_slice_hor_f32
106// CHECK: "arm_sme.intr.ld1w.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
107func.func @arm_sme_load_tile_slice_hor_f32(%src : memref<?x?xf32>, %mask : vector<[4]xi1>, %tile_slice_index : index) {
108  %c0 = arith.constant 0 : index
109  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>
110  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xf32>, vector<[4]xi1>, vector<[4]x[4]xf32>
111  "test.some_use" (%tile_update) : (vector<[4]x[4]xf32>) -> ()
112  return
113}
114
115// -----
116
117// CHECK-LABEL: @arm_sme_load_tile_slice_hor_f64
118// CHECK: "arm_sme.intr.ld1d.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
119func.func @arm_sme_load_tile_slice_hor_f64(%src : memref<?x?xf64>, %mask : vector<[2]xi1>, %tile_slice_index : index) {
120  %c0 = arith.constant 0 : index
121  %tile = arm_sme.get_tile : vector<[2]x[2]xf64>
122  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index : memref<?x?xf64>, vector<[2]xi1>, vector<[2]x[2]xf64>
123  "test.some_use" (%tile_update) : (vector<[2]x[2]xf64>) -> ()
124  return
125}
126
127// -----
128
129// CHECK-LABEL: @arm_sme_load_tile_slice_ver_i8
130// CHECK: "arm_sme.intr.ld1b.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, !llvm.ptr, i32) -> ()
131func.func @arm_sme_load_tile_slice_ver_i8(%src : memref<?x?xi8>, %mask : vector<[16]xi1>, %tile_slice_index : index) {
132  %c0 = arith.constant 0 : index
133  %tile = arm_sme.get_tile : vector<[16]x[16]xi8>
134  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xi8>, vector<[16]xi1>, vector<[16]x[16]xi8>
135  "test.some_use" (%tile_update) : (vector<[16]x[16]xi8>) -> ()
136  return
137}
138
139// -----
140
141// CHECK-LABEL: @arm_sme_load_tile_slice_ver_i16
142// CHECK: "arm_sme.intr.ld1h.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
143func.func @arm_sme_load_tile_slice_ver_i16(%src : memref<?x?xi16>, %mask : vector<[8]xi1>, %tile_slice_index : index) {
144  %c0 = arith.constant 0 : index
145  %tile = arm_sme.get_tile : vector<[8]x[8]xi16>
146  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xi16>, vector<[8]xi1>, vector<[8]x[8]xi16>
147  "test.some_use" (%tile_update) : (vector<[8]x[8]xi16>) -> ()
148  return
149}
150
151// -----
152
153// CHECK-LABEL: @arm_sme_load_tile_slice_ver_i32
154// CHECK: "arm_sme.intr.ld1w.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
155func.func @arm_sme_load_tile_slice_ver_i32(%src : memref<?x?xi32>, %mask : vector<[4]xi1>, %tile_slice_index : index) {
156  %c0 = arith.constant 0 : index
157  %tile = arm_sme.get_tile : vector<[4]x[4]xi32>
158  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xi32>, vector<[4]xi1>, vector<[4]x[4]xi32>
159  "test.some_use" (%tile_update) : (vector<[4]x[4]xi32>) -> ()
160  return
161}
162
163// -----
164
165// CHECK-LABEL: @arm_sme_load_tile_slice_ver_i64
166// CHECK: "arm_sme.intr.ld1d.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
167func.func @arm_sme_load_tile_slice_ver_i64(%src : memref<?x?xi64>, %mask : vector<[2]xi1>, %tile_slice_index : index) {
168  %c0 = arith.constant 0 : index
169  %tile = arm_sme.get_tile : vector<[2]x[2]xi64>
170  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xi64>, vector<[2]xi1>, vector<[2]x[2]xi64>
171  "test.some_use" (%tile_update) : (vector<[2]x[2]xi64>) -> ()
172  return
173}
174
175// -----
176
177// CHECK-LABEL: @arm_sme_load_tile_slice_ver_i128
178// CHECK: "arm_sme.intr.ld1q.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[1]xi1>, !llvm.ptr, i32) -> ()
179func.func @arm_sme_load_tile_slice_ver_i128(%src : memref<?x?xi128>, %mask : vector<[1]xi1>, %tile_slice_index : index) {
180  %c0 = arith.constant 0 : index
181  %tile = arm_sme.get_tile : vector<[1]x[1]xi128>
182  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xi128>, vector<[1]xi1>, vector<[1]x[1]xi128>
183  "test.some_use" (%tile_update) : (vector<[1]x[1]xi128>) -> ()
184  return
185}
186
187// -----
188
189// CHECK-LABEL: @arm_sme_load_tile_slice_ver_f16
190// CHECK: "arm_sme.intr.ld1h.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
191func.func @arm_sme_load_tile_slice_ver_f16(%src : memref<?x?xf16>, %mask : vector<[8]xi1>, %tile_slice_index : index) {
192  %c0 = arith.constant 0 : index
193  %tile = arm_sme.get_tile : vector<[8]x[8]xf16>
194  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xf16>, vector<[8]xi1>, vector<[8]x[8]xf16>
195  "test.some_use" (%tile_update) : (vector<[8]x[8]xf16>) -> ()
196  return
197}
198
199// -----
200
201// CHECK-LABEL: @arm_sme_load_tile_slice_ver_bf16
202// CHECK: "arm_sme.intr.ld1h.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
203func.func @arm_sme_load_tile_slice_ver_bf16(%src : memref<?x?xbf16>, %mask : vector<[8]xi1>, %tile_slice_index : index) {
204  %c0 = arith.constant 0 : index
205  %tile = arm_sme.get_tile : vector<[8]x[8]xbf16>
206  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xbf16>, vector<[8]xi1>, vector<[8]x[8]xbf16>
207  "test.some_use" (%tile_update) : (vector<[8]x[8]xbf16>) -> ()
208  return
209}
210
211// -----
212
213// CHECK-LABEL: @arm_sme_load_tile_slice_ver_f32
214// CHECK: "arm_sme.intr.ld1w.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
215func.func @arm_sme_load_tile_slice_ver_f32(%src : memref<?x?xf32>, %mask : vector<[4]xi1>, %tile_slice_index : index) {
216  %c0 = arith.constant 0 : index
217  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>
218  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xf32>, vector<[4]xi1>, vector<[4]x[4]xf32>
219  "test.some_use" (%tile_update) : (vector<[4]x[4]xf32>) -> ()
220  return
221}
222
223// -----
224
225// CHECK-LABEL: @arm_sme_load_tile_slice_ver_f64
226// CHECK: "arm_sme.intr.ld1d.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
227func.func @arm_sme_load_tile_slice_ver_f64(%src : memref<?x?xf64>, %mask : vector<[2]xi1>, %tile_slice_index : index) {
228  %c0 = arith.constant 0 : index
229  %tile = arm_sme.get_tile : vector<[2]x[2]xf64>
230  %tile_update = arm_sme.load_tile_slice %src[%c0], %mask, %tile, %tile_slice_index layout<vertical> : memref<?x?xf64>, vector<[2]xi1>, vector<[2]x[2]xf64>
231  "test.some_use" (%tile_update) : (vector<[2]x[2]xf64>) -> ()
232  return
233}
234
235//===----------------------------------------------------------------------===//
236// arm_sme.store_tile_slice
237//===----------------------------------------------------------------------===//
238
239// -----
240
241// CHECK-LABEL:   func.func @arm_sme_store_tile_slice_hor_i8(
242// CHECK-SAME:                                               %[[TILE_SLICE_INDEX:.*]]: index,
243// CHECK-SAME:                                               %[[MASK:.*]]: vector<[16]xi1>,
244// CHECK-SAME:                                               %[[DEST:.*]]: memref<?x?xi8>)
245// CHECK:           %[[C0:.*]] = arith.constant 0 : index
246// CHECK:           %[[MEM_DESC:.*]] = builtin.unrealized_conversion_cast %[[DEST]] : memref<?x?xi8> to !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
247// CHECK:           %[[C0_I64:.*]] = builtin.unrealized_conversion_cast %[[C0]] : index to i64
248// CHECK:           %[[ALIGNED_BASE:.*]] = llvm.extractvalue %[[MEM_DESC]][1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
249// CHECK:           %[[STRIDE:.*]] = llvm.extractvalue %[[MEM_DESC]][4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
250// CHECK:           %[[OFFSET:.*]] = llvm.mul %[[C0_I64]], %[[STRIDE]]  : i64
251// CHECK:           %[[GEP:.*]] = llvm.getelementptr %[[ALIGNED_BASE]]{{\[}}%[[OFFSET]]] : (!llvm.ptr, i64) -> !llvm.ptr, i8
252// CHECK:           %[[TILE_SLICE_INDEX_I32:.*]] = arith.index_castui %[[TILE_SLICE_INDEX]] : index to i32
253// CHECK:           "arm_sme.intr.st1b.horiz"(%[[MASK]], %[[GEP]], %[[TILE_SLICE_INDEX_I32]]) <{tile_id = 0 : i32}> : (vector<[16]xi1>, !llvm.ptr, i32) -> ()
254// CHECK:           return
255// CHECK:         }
256func.func @arm_sme_store_tile_slice_hor_i8(%tile_slice_index : index,  %mask : vector<[16]xi1>, %dest : memref<?x?xi8>) -> () {
257  %c0 = arith.constant 0 : index
258  %tile = arm_sme.get_tile : vector<[16]x[16]xi8>
259  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xi8>, vector<[16]xi1>, vector<[16]x[16]xi8>
260  return
261}
262
263// -----
264
265// CHECK-LABEL: @arm_sme_store_tile_slice_hor_i16
266// CHECK: "arm_sme.intr.st1h.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
267func.func @arm_sme_store_tile_slice_hor_i16(%tile_slice_index : index, %mask : vector<[8]xi1>, %dest : memref<?x?xi16>) -> () {
268  %c0 = arith.constant 0 : index
269  %tile = arm_sme.get_tile : vector<[8]x[8]xi16>
270  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xi16>, vector<[8]xi1>, vector<[8]x[8]xi16>
271  return
272}
273
274// -----
275
276// CHECK-LABEL: @arm_sme_store_tile_slice_hor_i32
277// CHECK: "arm_sme.intr.st1w.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
278func.func @arm_sme_store_tile_slice_hor_i32(%tile_slice_index : index, %mask : vector<[4]xi1>, %dest : memref<?x?xi32>) -> () {
279  %c0 = arith.constant 0 : index
280  %tile = arm_sme.get_tile : vector<[4]x[4]xi32>
281  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xi32>, vector<[4]xi1>, vector<[4]x[4]xi32>
282  return
283}
284
285// -----
286
287// CHECK-LABEL: @arm_sme_store_tile_slice_hor_i64
288// CHECK: "arm_sme.intr.st1d.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
289func.func @arm_sme_store_tile_slice_hor_i64(%tile_slice_index : index, %mask : vector<[2]xi1>, %dest : memref<?x?xi64>) -> () {
290  %c0 = arith.constant 0 : index
291  %tile = arm_sme.get_tile : vector<[2]x[2]xi64>
292  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xi64>, vector<[2]xi1>, vector<[2]x[2]xi64>
293  return
294}
295
296// -----
297
298// CHECK-LABEL: @arm_sme_store_tile_slice_hor_i128
299// CHECK: "arm_sme.intr.st1q.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[1]xi1>, !llvm.ptr, i32) -> ()
300func.func @arm_sme_store_tile_slice_hor_i128(%tile_slice_index : index, %mask : vector<[1]xi1>, %dest : memref<?x?xi128>) -> () {
301  %c0 = arith.constant 0 : index
302  %tile = arm_sme.get_tile : vector<[1]x[1]xi128>
303  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xi128>, vector<[1]xi1>, vector<[1]x[1]xi128>
304  return
305}
306
307// -----
308
309// CHECK-LABEL: @arm_sme_store_tile_slice_hor_f16
310// CHECK: "arm_sme.intr.st1h.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
311func.func @arm_sme_store_tile_slice_hor_f16(%tile_slice_index : index, %mask : vector<[8]xi1>, %dest : memref<?x?xf16>) -> () {
312  %c0 = arith.constant 0 : index
313  %tile = arm_sme.get_tile : vector<[8]x[8]xf16>
314  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xf16>, vector<[8]xi1>, vector<[8]x[8]xf16>
315  return
316}
317
318// -----
319
320// CHECK-LABEL: @arm_sme_store_tile_slice_hor_bf16
321// CHECK: "arm_sme.intr.st1h.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
322func.func @arm_sme_store_tile_slice_hor_bf16(%tile_slice_index : index, %mask : vector<[8]xi1>, %dest : memref<?x?xbf16>) -> () {
323  %c0 = arith.constant 0 : index
324  %tile = arm_sme.get_tile : vector<[8]x[8]xbf16>
325  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xbf16>, vector<[8]xi1>, vector<[8]x[8]xbf16>
326  return
327}
328
329// -----
330
331// CHECK-LABEL: @arm_sme_store_tile_slice_hor_f32
332// CHECK: "arm_sme.intr.st1w.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
333func.func @arm_sme_store_tile_slice_hor_f32(%tile_slice_index : index, %mask : vector<[4]xi1>, %dest : memref<?x?xf32>) -> () {
334  %c0 = arith.constant 0 : index
335  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>
336  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xf32>, vector<[4]xi1>, vector<[4]x[4]xf32>
337  return
338}
339
340// -----
341
342// CHECK-LABEL: @arm_sme_store_tile_slice_hor_f64
343// CHECK: "arm_sme.intr.st1d.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
344func.func @arm_sme_store_tile_slice_hor_f64(%tile_slice_index : index, %mask : vector<[2]xi1>, %dest : memref<?x?xf64>) -> () {
345  %c0 = arith.constant 0 : index
346  %tile = arm_sme.get_tile : vector<[2]x[2]xf64>
347  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] : memref<?x?xf64>, vector<[2]xi1>, vector<[2]x[2]xf64>
348  return
349}
350
351// -----
352
353// CHECK-LABEL: @arm_sme_store_tile_slice_ver_i8
354// CHECK: "arm_sme.intr.st1b.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, !llvm.ptr, i32) -> ()
355func.func @arm_sme_store_tile_slice_ver_i8(%tile_slice_index : index, %mask : vector<[16]xi1>, %dest : memref<?x?xi8>) -> () {
356  %c0 = arith.constant 0 : index
357  %tile = arm_sme.get_tile : vector<[16]x[16]xi8>
358  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xi8>, vector<[16]xi1>, vector<[16]x[16]xi8>
359  return
360}
361
362// -----
363
364// CHECK-LABEL: @arm_sme_store_tile_slice_ver_i16
365// CHECK: "arm_sme.intr.st1h.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
366func.func @arm_sme_store_tile_slice_ver_i16(%tile_slice_index : index, %mask : vector<[8]xi1>, %dest : memref<?x?xi16>) -> () {
367  %c0 = arith.constant 0 : index
368  %tile = arm_sme.get_tile : vector<[8]x[8]xi16>
369  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xi16>, vector<[8]xi1>, vector<[8]x[8]xi16>
370  return
371}
372
373// -----
374
375// CHECK-LABEL: @arm_sme_store_tile_slice_ver_i32
376// CHECK: "arm_sme.intr.st1w.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
377func.func @arm_sme_store_tile_slice_ver_i32(%tile_slice_index : index, %mask : vector<[4]xi1>, %dest : memref<?x?xi32>) -> () {
378  %c0 = arith.constant 0 : index
379  %tile = arm_sme.get_tile : vector<[4]x[4]xi32>
380  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xi32>, vector<[4]xi1>, vector<[4]x[4]xi32>
381  return
382}
383
384// -----
385
386// CHECK-LABEL: @arm_sme_store_tile_slice_ver_i64
387// CHECK: "arm_sme.intr.st1d.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
388func.func @arm_sme_store_tile_slice_ver_i64(%tile_slice_index : index, %mask : vector<[2]xi1>, %dest : memref<?x?xi64>) -> () {
389  %c0 = arith.constant 0 : index
390  %tile = arm_sme.get_tile : vector<[2]x[2]xi64>
391  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xi64>, vector<[2]xi1>, vector<[2]x[2]xi64>
392  return
393}
394
395// -----
396
397// CHECK-LABEL: @arm_sme_store_tile_slice_ver_i128
398// CHECK: "arm_sme.intr.st1q.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[1]xi1>, !llvm.ptr, i32) -> ()
399func.func @arm_sme_store_tile_slice_ver_i128(%tile_slice_index : index, %mask : vector<[1]xi1>, %dest : memref<?x?xi128>) -> () {
400  %c0 = arith.constant 0 : index
401  %tile = arm_sme.get_tile : vector<[1]x[1]xi128>
402  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xi128>, vector<[1]xi1>, vector<[1]x[1]xi128>
403  return
404}
405
406// -----
407
408// CHECK-LABEL: @arm_sme_store_tile_slice_ver_f16
409// CHECK: "arm_sme.intr.st1h.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
410func.func @arm_sme_store_tile_slice_ver_f16(%tile_slice_index : index, %mask : vector<[8]xi1>, %dest : memref<?x?xf16>) -> () {
411  %c0 = arith.constant 0 : index
412  %tile = arm_sme.get_tile : vector<[8]x[8]xf16>
413  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xf16>, vector<[8]xi1>, vector<[8]x[8]xf16>
414  return
415}
416
417// -----
418
419// CHECK-LABEL: @arm_sme_store_tile_slice_ver_bf16
420// CHECK: "arm_sme.intr.st1h.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, !llvm.ptr, i32) -> ()
421func.func @arm_sme_store_tile_slice_ver_bf16(%tile_slice_index : index, %mask : vector<[8]xi1>, %dest : memref<?x?xbf16>) -> () {
422  %c0 = arith.constant 0 : index
423  %tile = arm_sme.get_tile : vector<[8]x[8]xbf16>
424  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xbf16>, vector<[8]xi1>, vector<[8]x[8]xbf16>
425  return
426}
427
428// -----
429
430// CHECK-LABEL: @arm_sme_store_tile_slice_ver_f32
431// CHECK: "arm_sme.intr.st1w.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi1>, !llvm.ptr, i32) -> ()
432func.func @arm_sme_store_tile_slice_ver_f32(%tile_slice_index : index, %mask : vector<[4]xi1>, %dest : memref<?x?xf32>) -> () {
433  %c0 = arith.constant 0 : index
434  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>
435  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xf32>, vector<[4]xi1>, vector<[4]x[4]xf32>
436  return
437}
438
439// -----
440
441// CHECK-LABEL: @arm_sme_store_tile_slice_ver_f64
442// CHECK: "arm_sme.intr.st1d.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi1>, !llvm.ptr, i32) -> ()
443func.func @arm_sme_store_tile_slice_ver_f64(%tile_slice_index : index, %mask : vector<[2]xi1>, %dest : memref<?x?xf64>) -> () {
444  %c0 = arith.constant 0 : index
445  %tile = arm_sme.get_tile : vector<[2]x[2]xf64>
446  arm_sme.store_tile_slice %tile, %tile_slice_index, %mask, %dest[%c0] layout<vertical> : memref<?x?xf64>, vector<[2]xi1>, vector<[2]x[2]xf64>
447  return
448}
449
450//===----------------------------------------------------------------------===//
451// arm_sme.insert_tile_slice
452//===----------------------------------------------------------------------===//
453
454// -----
455
456// CHECK-LABEL: @arm_sme_insert_tile_slice_hor_i32
457// CHECK: "arm_sme.intr.write.horiz"({{.*}}) <{tile_id = 0 : i32}> : (i32, vector<[4]xi1>, vector<[4]xi32>) -> ()
458func.func @arm_sme_insert_tile_slice_hor_i32(%vector : vector<[4]xi32>, %tile_slice_index : index) -> () {
459  %c0 = arith.constant 0 : index
460  %tile = arm_sme.get_tile : vector<[4]x[4]xi32>
461  %tile_update = arm_sme.insert_tile_slice %vector, %tile[%tile_slice_index] : vector<[4]xi32> into vector<[4]x[4]xi32>
462  "test.some_use" (%tile_update) : (vector<[4]x[4]xi32>) -> ()
463  return
464}
465
466// -----
467
468// CHECK-LABEL: @arm_sme_insert_tile_slice_ver_bf16
469// CHECK: "arm_sme.intr.write.vert"({{.*}}) <{tile_id = 0 : i32}> : (i32, vector<[8]xi1>, vector<[8]xbf16>) -> ()
470func.func @arm_sme_insert_tile_slice_ver_bf16(%vector : vector<[8]xbf16>, %tile_slice_index : index) -> () {
471  %c0 = arith.constant 0 : index
472  %tile = arm_sme.get_tile : vector<[8]x[8]xbf16>
473  %tile_update =  arm_sme.insert_tile_slice %vector, %tile[%tile_slice_index] layout<vertical> : vector<[8]xbf16> into vector<[8]x[8]xbf16>
474  "test.some_use" (%tile_update) : (vector<[8]x[8]xbf16>) -> ()
475  return
476}
477
478//===----------------------------------------------------------------------===//
479// arm_sme.extract_tile_slice
480//===----------------------------------------------------------------------===//
481
482// -----
483
484// CHECK-LABEL: @arm_sme_extract_tile_slice_i8
485// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi8>, vector<[16]xi1>, i32) -> vector<[16]xi8>
486func.func @arm_sme_extract_tile_slice_i8(%tile_slice_index : index) -> vector<[16]xi8> {
487  %tile = arm_sme.get_tile : vector<[16]x[16]xi8>
488  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[16]xi8> from vector<[16]x[16]xi8>
489  return %slice : vector<[16]xi8>
490}
491
492// -----
493
494// CHECK-LABEL: @arm_sme_extract_tile_slice_i16
495// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi16>, vector<[8]xi1>, i32) -> vector<[8]xi16>
496func.func @arm_sme_extract_tile_slice_i16(%tile_slice_index : index) -> vector<[8]xi16> {
497  %tile = arm_sme.get_tile : vector<[8]x[8]xi16>
498  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[8]xi16> from vector<[8]x[8]xi16>
499  return %slice : vector<[8]xi16>
500}
501
502// -----
503
504// CHECK-LABEL: @arm_sme_extract_tile_slice_i32
505// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xi32>, vector<[4]xi1>, i32) -> vector<[4]xi32>
506func.func @arm_sme_extract_tile_slice_i32(%tile_slice_index : index) -> vector<[4]xi32> {
507  %tile = arm_sme.get_tile : vector<[4]x[4]xi32>
508  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[4]xi32> from vector<[4]x[4]xi32>
509  return %slice : vector<[4]xi32>
510}
511
512// -----
513
514// CHECK-LABEL: @arm_sme_extract_tile_slice_i64
515// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xi64>, vector<[2]xi1>, i32) -> vector<[2]xi64>
516func.func @arm_sme_extract_tile_slice_i64(%tile_slice_index : index) -> vector<[2]xi64> {
517  %tile = arm_sme.get_tile : vector<[2]x[2]xi64>
518  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[2]xi64> from vector<[2]x[2]xi64>
519  return %slice : vector<[2]xi64>
520}
521
522// -----
523
524// CHECK-LABEL: @arm_sme_extract_tile_slice_i128
525// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[1]xi128>, vector<[1]xi1>, i32) -> vector<[1]xi128>
526func.func @arm_sme_extract_tile_slice_i128(%tile_slice_index : index) -> vector<[1]xi128> {
527  %tile = arm_sme.get_tile : vector<[1]x[1]xi128>
528  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[1]xi128> from vector<[1]x[1]xi128>
529  return %slice : vector<[1]xi128>
530}
531
532// -----
533
534// CHECK-LABEL: @arm_sme_extract_tile_slice_f16
535// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xf16>, vector<[8]xi1>, i32) -> vector<[8]xf16>
536func.func @arm_sme_extract_tile_slice_f16(%tile_slice_index : index) -> vector<[8]xf16> {
537  %tile = arm_sme.get_tile : vector<[8]x[8]xf16>
538  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[8]xf16> from vector<[8]x[8]xf16>
539  return %slice : vector<[8]xf16>
540}
541
542// -----
543
544// CHECK-LABEL: @arm_sme_extract_tile_slice_bf16
545// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xbf16>, vector<[8]xi1>, i32) -> vector<[8]xbf16>
546func.func @arm_sme_extract_tile_slice_bf16(%tile_slice_index : index) -> vector<[8]xbf16> {
547  %tile = arm_sme.get_tile : vector<[8]x[8]xbf16>
548  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[8]xbf16> from vector<[8]x[8]xbf16>
549  return %slice : vector<[8]xbf16>
550}
551
552// -----
553
554// CHECK-LABEL: @arm_sme_extract_tile_slice_f32
555// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[4]xf32>, vector<[4]xi1>, i32) -> vector<[4]xf32>
556func.func @arm_sme_extract_tile_slice_f32(%tile_slice_index : index) -> vector<[4]xf32> {
557  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>
558  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[4]xf32> from vector<[4]x[4]xf32>
559  return %slice : vector<[4]xf32>
560}
561
562// -----
563
564// CHECK-LABEL: @arm_sme_extract_tile_slice_f64
565// CHECK: "arm_sme.intr.read.horiz"({{.*}}) <{tile_id = 0 : i32}> : (vector<[2]xf64>, vector<[2]xi1>, i32) -> vector<[2]xf64>
566func.func @arm_sme_extract_tile_slice_f64(%tile_slice_index : index) -> vector<[2]xf64> {
567  %tile = arm_sme.get_tile : vector<[2]x[2]xf64>
568  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] : vector<[2]xf64> from vector<[2]x[2]xf64>
569  return %slice : vector<[2]xf64>
570}
571
572// -----
573
574// CHECK-LABEL: @arm_sme_extract_tile_slice_ver_i128
575// CHECK: "arm_sme.intr.read.vert"({{.*}}) <{tile_id = 0 : i32}> : (vector<[1]xi128>, vector<[1]xi1>, i32) -> vector<[1]xi128>
576func.func @arm_sme_extract_tile_slice_ver_i128(%tile_slice_index : index) -> vector<[1]xi128> {
577  %tile = arm_sme.get_tile : vector<[1]x[1]xi128>
578  %slice = arm_sme.extract_tile_slice %tile[%tile_slice_index] layout<vertical> : vector<[1]xi128> from vector<[1]x[1]xi128>
579  return %slice : vector<[1]xi128>
580}
581
582//===----------------------------------------------------------------------===//
583// arm_sme.streaming_vl
584//===----------------------------------------------------------------------===//
585
586// -----
587
588// CHECK-LABEL: @arm_sme_streaming_vl_bytes
589// CHECK: %[[COUNT:.*]] = "arm_sme.intr.cntsb"() : () -> i64
590// CHECK: %[[INDEX_COUNT:.*]] = arith.index_cast %[[COUNT]] : i64 to index
591// CHECK: return %[[INDEX_COUNT]] : index
592func.func @arm_sme_streaming_vl_bytes() -> index {
593  %svl_b = arm_sme.streaming_vl <byte>
594  return %svl_b : index
595}
596
597// -----
598
599// CHECK-LABEL: @arm_sme_streaming_vl_half_words
600// CHECK: "arm_sme.intr.cntsh"() : () -> i64
601func.func @arm_sme_streaming_vl_half_words() -> index {
602  %svl_h = arm_sme.streaming_vl <half>
603  return %svl_h : index
604}
605
606// -----
607
608// CHECK-LABEL: @arm_sme_streaming_vl_words
609// CHECK: "arm_sme.intr.cntsw"() : () -> i64
610func.func @arm_sme_streaming_vl_words() -> index {
611  %svl_w = arm_sme.streaming_vl <word>
612  return %svl_w : index
613}
614
615// -----
616
617// CHECK-LABEL: @arm_sme_streaming_vl_double_words
618// CHECK: "arm_sme.intr.cntsd"() : () -> i64
619func.func @arm_sme_streaming_vl_double_words() -> index {
620  %svl_d = arm_sme.streaming_vl <double>
621  return %svl_d : index
622}
623
624//===----------------------------------------------------------------------===//
625// arm_sme.fmopa_2way
626//===----------------------------------------------------------------------===//
627
628// -----
629
630// CHECK-LABEL: arm_sme_fmopa_2way_f16f16_to_f32
631// CHECK: "arm_sme.intr.mopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xf16>, vector<[8]xf16>) -> ()
632func.func @arm_sme_fmopa_2way_f16f16_to_f32(%vecA: vector<[8]xf16>, %vecB: vector<[8]xf16>) {
633  %result = arm_sme.fmopa_2way %vecA, %vecB : vector<[8]xf16>, vector<[8]xf16> into vector<[4]x[4]xf32>
634  "test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
635}
636
637// -----
638
639// CHECK-LABEL: arm_sme_fmopa_2way_bf16bf16_to_f32
640// CHECK: "arm_sme.intr.mopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xbf16>, vector<[8]xbf16>) -> ()
641func.func @arm_sme_fmopa_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: vector<[8]xbf16>) {
642  %result = arm_sme.fmopa_2way %vecA, %vecB : vector<[8]xbf16>, vector<[8]xbf16> into vector<[4]x[4]xf32>
643  "test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
644}
645
646//===----------------------------------------------------------------------===//
647// arm_sme.fmops_2way
648//===----------------------------------------------------------------------===//
649
650// -----
651
652// CHECK-LABEL: arm_sme_fmops_2way_f16f16_to_f32
653// CHECK: "arm_sme.intr.mops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xf16>, vector<[8]xf16>) -> ()
654func.func @arm_sme_fmops_2way_f16f16_to_f32(%vecA: vector<[8]xf16>, %vecB: vector<[8]xf16>) {
655  %result = arm_sme.fmops_2way %vecA, %vecB : vector<[8]xf16>, vector<[8]xf16> into vector<[4]x[4]xf32>
656  "test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
657}
658
659// -----
660
661// CHECK-LABEL: arm_sme_fmops_2way_bf16bf16_to_f32
662// CHECK: "arm_sme.intr.mops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xbf16>, vector<[8]xbf16>) -> ()
663func.func @arm_sme_fmops_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: vector<[8]xbf16>) {
664  %result = arm_sme.fmops_2way %vecA, %vecB : vector<[8]xbf16>, vector<[8]xbf16> into vector<[4]x[4]xf32>
665  "test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
666}
667
668//===----------------------------------------------------------------------===//
669// arm_sme.smopa_2way
670//===----------------------------------------------------------------------===//
671
672// -----
673
674// CHECK-LABEL: arm_sme_smopa_2way_i16i16_to_i32
675// CHECK: "arm_sme.intr.smopa.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
676func.func @arm_sme_smopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
677  %result = arm_sme.smopa_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
678  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
679}
680
681//===----------------------------------------------------------------------===//
682// arm_sme.smops_2way
683//===----------------------------------------------------------------------===//
684
685// -----
686
687// CHECK-LABEL: arm_sme_smops_2way_i16i16_to_i32
688// CHECK: "arm_sme.intr.smops.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
689func.func @arm_sme_smops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
690  %result = arm_sme.smops_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
691  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
692}
693
694//===----------------------------------------------------------------------===//
695// arm_sme.umopa_2way
696//===----------------------------------------------------------------------===//
697
698// -----
699
700// CHECK-LABEL: arm_sme_umopa_2way_i16i16_to_i32
701// CHECK: "arm_sme.intr.umopa.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
702func.func @arm_sme_umopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
703  %result = arm_sme.umopa_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
704  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
705  return
706}
707
708//===----------------------------------------------------------------------===//
709// arm_sme.umops_2way
710//===----------------------------------------------------------------------===//
711
712// -----
713
714// CHECK-LABEL: arm_sme_umops_2way_i16i16_to_i32
715// CHECK: "arm_sme.intr.umops.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
716func.func @arm_sme_umops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
717  %result = arm_sme.umops_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
718  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
719  return
720}
721
722//===----------------------------------------------------------------------===//
723// arm_sme.smopa_4way
724//===----------------------------------------------------------------------===//
725
726// -----
727
728// CHECK-LABEL: arm_sme_smopa_4way_i8i8_to_i32
729// CHECK: "arm_sme.intr.smopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
730func.func @arm_sme_smopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
731  %result = arm_sme.smopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
732  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
733  return
734}
735
736// -----
737
738// CHECK-LABEL: arm_sme_smopa_4way_i16i16_to_i64
739// CHECK: "arm_sme.intr.smopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
740func.func @arm_sme_smopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
741  %result = arm_sme.smopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
742  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
743  return
744}
745
746//===----------------------------------------------------------------------===//
747// arm_sme.smops_4way
748//===----------------------------------------------------------------------===//
749
750// -----
751
752// CHECK-LABEL: arm_sme_smops_4way_i8i8_to_i32
753// CHECK: "arm_sme.intr.smops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
754func.func @arm_sme_smops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
755  %result = arm_sme.smops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
756  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
757  return
758}
759
760// -----
761
762// CHECK-LABEL: arm_sme_smops_4way_i16i16_to_i64
763// CHECK: "arm_sme.intr.smops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
764func.func @arm_sme_smops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
765  %result = arm_sme.smops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
766  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
767  return
768}
769
770//===----------------------------------------------------------------------===//
771// arm_sme.umopa_4way
772//===----------------------------------------------------------------------===//
773
774// -----
775
776// CHECK-LABEL: arm_sme_umopa_4way_i8i8_to_i32
777// CHECK: "arm_sme.intr.umopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
778func.func @arm_sme_umopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
779  %result = arm_sme.umopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
780  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
781  return
782}
783
784// -----
785
786// CHECK-LABEL: arm_sme_umopa_4way_i16i16_to_i64
787// CHECK: "arm_sme.intr.umopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
788func.func @arm_sme_umopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
789  %result = arm_sme.umopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
790  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
791  return
792}
793
794//===----------------------------------------------------------------------===//
795// arm_sme.umops_4way
796//===----------------------------------------------------------------------===//
797
798// -----
799
800// CHECK-LABEL: arm_sme_umops_4way_i8i8_to_i32
801// CHECK: "arm_sme.intr.umops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
802func.func @arm_sme_umops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
803  %result = arm_sme.umops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
804  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
805  return
806}
807
808// -----
809
810// CHECK-LABEL: arm_sme_umops_4way_i16i16_to_i64
811// CHECK: "arm_sme.intr.umops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
812func.func @arm_sme_umops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
813  %result = arm_sme.umops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
814  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
815  return
816}
817
818//===----------------------------------------------------------------------===//
819// arm_sme.sumopa_4way
820//===----------------------------------------------------------------------===//
821
822// -----
823
824// CHECK-LABEL: arm_sme_sumopa_4way_i8i8_to_i32
825// CHECK: "arm_sme.intr.sumopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
826func.func @arm_sme_sumopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
827  %result = arm_sme.sumopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
828  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
829  return
830}
831
832// -----
833
834// CHECK-LABEL: arm_sme_sumopa_4way_i16i16_to_i64
835// CHECK: "arm_sme.intr.sumopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
836func.func @arm_sme_sumopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
837  %result = arm_sme.sumopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
838  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
839  return
840}
841
842//===----------------------------------------------------------------------===//
843// arm_sme.sumops_4way
844//===----------------------------------------------------------------------===//
845
846// -----
847
848// CHECK-LABEL: arm_sme_sumops_4way_i8i8_to_i32
849// CHECK: "arm_sme.intr.sumops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
850func.func @arm_sme_sumops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
851  %result = arm_sme.sumops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
852  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
853  return
854}
855
856// -----
857
858// CHECK-LABEL: arm_sme_sumops_4way_i16i16_to_i64
859// CHECK: "arm_sme.intr.sumops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
860func.func @arm_sme_sumops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
861  %result = arm_sme.sumops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
862  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
863  return
864}
865
866//===----------------------------------------------------------------------===//
867// arm_sme.usmopa_4way
868//===----------------------------------------------------------------------===//
869
870// -----
871
872// CHECK-LABEL: arm_sme_usmopa_4way_i8i8_to_i32
873// CHECK: "arm_sme.intr.usmopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
874func.func @arm_sme_usmopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
875  %result = arm_sme.usmopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
876  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
877  return
878}
879
880// -----
881
882// CHECK-LABEL: arm_sme_usmopa_4way_i16i16_to_i64
883// CHECK: "arm_sme.intr.usmopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
884func.func @arm_sme_usmopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
885  %result = arm_sme.usmopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
886  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
887  return
888}
889
890//===----------------------------------------------------------------------===//
891// arm_sme.usmops_4way
892//===----------------------------------------------------------------------===//
893
894// -----
895
896// CHECK-LABEL: arm_sme_usmops_4way_i8i8_to_i32
897// CHECK: "arm_sme.intr.usmops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
898func.func @arm_sme_usmops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
899  %result = arm_sme.usmops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
900  "test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
901  return
902}
903
904// -----
905
906// CHECK-LABEL: arm_sme_usmops_4way_i16i16_to_i64
907// CHECK: "arm_sme.intr.usmops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
908func.func @arm_sme_usmops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
909  %result = arm_sme.usmops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
910  "test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
911  return
912}
913
914//===----------------------------------------------------------------------===//
915// Operations on SME tile types allowed after conversion
916//===----------------------------------------------------------------------===//
917
918// -----
919
920// The following operations on SME tile types are permitted after conversion:
921//
922//   - arm_sme.copy_tile
923//   - arm_sme.get_tile
924//   - cf.br
925//   - any unregistered op such as 'test.some_use'.
926//
927// this test verifies this. Conversion will fail for operations with SME tile
928// types not in this list, this is tested in 'unsupported.mlir'.
929
930func.func @ops_on_tiles_legal_post_conversion(%ub : index) {
931  %c0 = arith.constant 0 : index
932  %c1 = arith.constant 1 : index
933  %tile = arm_sme.get_tile : vector<[4]x[4]xf32>
934  %copy = arm_sme.copy_tile %tile : vector<[4]x[4]xf32>
935  cf.br ^bb1(%copy : vector<[4]x[4]xf32>)
936^bb1(%x : vector<[4]x[4]xf32>):
937  "test.some_use"(%x) : (vector<[4]x[4]xf32>) -> ()
938  return
939}
940