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