1// RUN: mlir-opt %s | mlir-opt | FileCheck %s 2 3// CHECK-LABEL: func @vector_transfer_ops_0d( 4func.func @vector_transfer_ops_0d(%arg0: tensor<f32>, %arg1: memref<f32>) 5 -> tensor<f32> { 6 %f0 = arith.constant 0.0 : f32 7 %0 = vector.transfer_read %arg0[], %f0 {permutation_map = affine_map<()->()>} : 8 tensor<f32>, vector<f32> 9 %1 = vector.transfer_write %0, %arg0[] {permutation_map = affine_map<()->()>} : 10 vector<f32>, tensor<f32> 11 %2 = vector.transfer_read %arg1[], %f0 {permutation_map = affine_map<()->()>} : 12 memref<f32>, vector<f32> 13 vector.transfer_write %2, %arg1[] {permutation_map = affine_map<()->()>} : 14 vector<f32>, memref<f32> 15 return %1: tensor<f32> 16} 17 18// CHECK-LABEL: func @vector_transfer_ops_0d_from_higher_d( 19func.func @vector_transfer_ops_0d_from_higher_d(%arg0: tensor<?xf32>, %arg1: memref<?x?xf32>) 20 -> tensor<?xf32> { 21 %c0 = arith.constant 0 : index 22 %f0 = arith.constant 0.0 : f32 23 %0 = vector.transfer_read %arg0[%c0], %f0 {permutation_map = affine_map<(d0)->()>} : 24 tensor<?xf32>, vector<f32> 25 %1 = vector.transfer_write %0, %arg0[%c0] {permutation_map = affine_map<(d0)->()>} : 26 vector<f32>, tensor<?xf32> 27 %2 = vector.transfer_read %arg1[%c0, %c0], %f0 {permutation_map = affine_map<(d0, d1)->()>} : 28 memref<?x?xf32>, vector<f32> 29 vector.transfer_write %2, %arg1[%c0, %c0] {permutation_map = affine_map<(d0, d1)->()>} : 30 vector<f32>, memref<?x?xf32> 31 return %1: tensor<?xf32> 32} 33 34// CHECK-LABEL: func @vector_transfer_ops( 35func.func @vector_transfer_ops(%arg0: memref<?x?xf32>, 36 %arg1 : memref<?x?xvector<4x3xf32>>, 37 %arg2 : memref<?x?xvector<4x3xi32>>, 38 %arg3 : memref<?x?xvector<4x3xindex>>, 39 %arg4 : memref<?x?x?xf32>) { 40 // CHECK: %[[C3:.*]] = arith.constant 3 : index 41 %c3 = arith.constant 3 : index 42 %cst = arith.constant 3.0 : f32 43 %f0 = arith.constant 0.0 : f32 44 %c0 = arith.constant 0 : i32 45 %i0 = arith.constant 0 : index 46 %i1 = arith.constant 1 : i1 47 48 %vf0 = vector.splat %f0 : vector<4x3xf32> 49 %v0 = vector.splat %c0 : vector<4x3xi32> 50 %vi0 = vector.splat %i0 : vector<4x3xindex> 51 %m = arith.constant dense<[0, 0, 1, 0, 1]> : vector<5xi1> 52 %m2 = vector.splat %i1 : vector<4x5xi1> 53 // 54 // CHECK: vector.transfer_read 55 %0 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d0)>} : memref<?x?xf32>, vector<128xf32> 56 // CHECK: vector.transfer_read 57 %1 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : memref<?x?xf32>, vector<3x7xf32> 58 // CHECK: vector.transfer_read 59 %2 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d0)>} : memref<?x?xf32>, vector<128xf32> 60 // CHECK: vector.transfer_read 61 %3 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d1)>} : memref<?x?xf32>, vector<128xf32> 62 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 63 %4 = vector.transfer_read %arg1[%c3, %c3], %vf0 {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 64 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} {in_bounds = [false, true]} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 65 %5 = vector.transfer_read %arg1[%c3, %c3], %vf0 {in_bounds = [false, true]} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 66 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : memref<?x?xvector<4x3xi32>>, vector<5x24xi8> 67 %6 = vector.transfer_read %arg2[%c3, %c3], %v0 : memref<?x?xvector<4x3xi32>>, vector<5x24xi8> 68 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : memref<?x?xvector<4x3xindex>>, vector<5x48xi8> 69 %7 = vector.transfer_read %arg3[%c3, %c3], %vi0 : memref<?x?xvector<4x3xindex>>, vector<5x48xi8> 70 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}}, %{{.*}} : memref<?x?xf32>, vector<5xf32> 71 %8 = vector.transfer_read %arg0[%c3, %c3], %f0, %m : memref<?x?xf32>, vector<5xf32> 72 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]], %[[C3]]], %{{.*}}, %{{.*}} : memref<?x?x?xf32>, vector<5x4x8xf32> 73 %9 = vector.transfer_read %arg4[%c3, %c3, %c3], %f0, %m2 {permutation_map = affine_map<(d0, d1, d2)->(d1, d0, 0)>} : memref<?x?x?xf32>, vector<5x4x8xf32> 74 75 // CHECK: vector.transfer_write 76 vector.transfer_write %0, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0)>} : vector<128xf32>, memref<?x?xf32> 77 // CHECK: vector.transfer_write 78 vector.transfer_write %1, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : vector<3x7xf32>, memref<?x?xf32> 79 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 80 vector.transfer_write %4, %arg1[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 81 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 82 vector.transfer_write %5, %arg1[%c3, %c3] {in_bounds = [false, false]} : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 83 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<5x24xi8>, memref<?x?xvector<4x3xi32>> 84 vector.transfer_write %6, %arg2[%c3, %c3] : vector<5x24xi8>, memref<?x?xvector<4x3xi32>> 85 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<5x48xi8>, memref<?x?xvector<4x3xindex>> 86 vector.transfer_write %7, %arg3[%c3, %c3] : vector<5x48xi8>, memref<?x?xvector<4x3xindex>> 87 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : vector<5xf32>, memref<?x?xf32> 88 vector.transfer_write %8, %arg0[%c3, %c3], %m : vector<5xf32>, memref<?x?xf32> 89 90 return 91} 92 93 94// CHECK-LABEL: func @vector_transfer_ops_tensor( 95func.func @vector_transfer_ops_tensor(%arg0: tensor<?x?xf32>, 96 %arg1 : tensor<?x?xvector<4x3xf32>>, 97 %arg2 : tensor<?x?xvector<4x3xi32>>, 98 %arg3 : tensor<?x?xvector<4x3xindex>>) -> 99 (tensor<?x?xf32>, tensor<?x?xf32>, tensor<?x?xvector<4x3xf32>>, 100 tensor<?x?xvector<4x3xf32>>, tensor<?x?xvector<4x3xi32>>, 101 tensor<?x?xvector<4x3xindex>>){ 102 // CHECK: %[[C3:.*]] = arith.constant 3 : index 103 %c3 = arith.constant 3 : index 104 %cst = arith.constant 3.0 : f32 105 %f0 = arith.constant 0.0 : f32 106 %c0 = arith.constant 0 : i32 107 %i0 = arith.constant 0 : index 108 109 %vf0 = vector.splat %f0 : vector<4x3xf32> 110 %v0 = vector.splat %c0 : vector<4x3xi32> 111 %vi0 = vector.splat %i0 : vector<4x3xindex> 112 113 // 114 // CHECK: vector.transfer_read 115 %0 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d0)>} : tensor<?x?xf32>, vector<128xf32> 116 // CHECK: vector.transfer_read 117 %1 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : tensor<?x?xf32>, vector<3x7xf32> 118 // CHECK: vector.transfer_read 119 %2 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d0)>} : tensor<?x?xf32>, vector<128xf32> 120 // CHECK: vector.transfer_read 121 %3 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d1)>} : tensor<?x?xf32>, vector<128xf32> 122 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 123 %4 = vector.transfer_read %arg1[%c3, %c3], %vf0 {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 124 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} {in_bounds = [false, true]} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 125 %5 = vector.transfer_read %arg1[%c3, %c3], %vf0 {in_bounds = [false, true]} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 126 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : tensor<?x?xvector<4x3xi32>>, vector<5x24xi8> 127 %6 = vector.transfer_read %arg2[%c3, %c3], %v0 : tensor<?x?xvector<4x3xi32>>, vector<5x24xi8> 128 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : tensor<?x?xvector<4x3xindex>>, vector<5x48xi8> 129 %7 = vector.transfer_read %arg3[%c3, %c3], %vi0 : tensor<?x?xvector<4x3xindex>>, vector<5x48xi8> 130 131 132 // CHECK: vector.transfer_write 133 %8 = vector.transfer_write %0, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0)>} : vector<128xf32>, tensor<?x?xf32> 134 // CHECK: vector.transfer_write 135 %9 = vector.transfer_write %1, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : vector<3x7xf32>, tensor<?x?xf32> 136 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 137 %10 = vector.transfer_write %4, %arg1[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 138 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 139 %11 = vector.transfer_write %5, %arg1[%c3, %c3] {in_bounds = [false, false]} : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 140 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<5x24xi8>, tensor<?x?xvector<4x3xi32>> 141 %12 = vector.transfer_write %6, %arg2[%c3, %c3] : vector<5x24xi8>, tensor<?x?xvector<4x3xi32>> 142 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<5x48xi8>, tensor<?x?xvector<4x3xindex>> 143 %13 = vector.transfer_write %7, %arg3[%c3, %c3] : vector<5x48xi8>, tensor<?x?xvector<4x3xindex>> 144 145 return %8, %9, %10, %11, %12, %13 : 146 tensor<?x?xf32>, tensor<?x?xf32>, tensor<?x?xvector<4x3xf32>>, 147 tensor<?x?xvector<4x3xf32>>, tensor<?x?xvector<4x3xi32>>, 148 tensor<?x?xvector<4x3xindex>> 149} 150 151// CHECK-LABEL: @vector_broadcast 152func.func @vector_broadcast(%a: f32, %b: vector<f32>, %c: vector<16xf32>, %d: vector<1x16xf32>, %e: vector<8x1xf32>) -> vector<8x16xf32> { 153 // CHECK: vector.broadcast %{{.*}} : f32 to vector<f32> 154 %0 = vector.broadcast %a : f32 to vector<f32> 155 // CHECK: vector.broadcast %{{.*}} : vector<f32> to vector<4xf32> 156 %1 = vector.broadcast %b : vector<f32> to vector<4xf32> 157 // CHECK: vector.broadcast %{{.*}} : f32 to vector<16xf32> 158 %2 = vector.broadcast %a : f32 to vector<16xf32> 159 // CHECK-NEXT: vector.broadcast %{{.*}} : vector<16xf32> to vector<8x16xf32> 160 %3 = vector.broadcast %c : vector<16xf32> to vector<8x16xf32> 161 // CHECK-NEXT: vector.broadcast %{{.*}} : vector<1x16xf32> to vector<8x16xf32> 162 %4 = vector.broadcast %d : vector<1x16xf32> to vector<8x16xf32> 163 // CHECK-NEXT: vector.broadcast %{{.*}} : vector<8x1xf32> to vector<8x16xf32> 164 %5 = vector.broadcast %e : vector<8x1xf32> to vector<8x16xf32> 165 return %4 : vector<8x16xf32> 166} 167 168// CHECK-LABEL: @shuffle0D 169func.func @shuffle0D(%a: vector<f32>) -> vector<3xf32> { 170 // CHECK: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 0] : vector<f32>, vector<f32> 171 %1 = vector.shuffle %a, %a[0, 1, 0] : vector<f32>, vector<f32> 172 return %1 : vector<3xf32> 173} 174 175// CHECK-LABEL: @shuffle1D 176func.func @shuffle1D(%a: vector<2xf32>, %b: vector<4xf32>) -> vector<2xf32> { 177 // CHECK: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 2, 3] : vector<2xf32>, vector<2xf32> 178 %1 = vector.shuffle %a, %a[0, 1, 2, 3] : vector<2xf32>, vector<2xf32> 179 // CHECK-NEXT: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 2] : vector<4xf32>, vector<4xf32> 180 %2 = vector.shuffle %1, %b[0, 1, 2] : vector<4xf32>, vector<4xf32> 181 // CHECK-NEXT: vector.shuffle %{{.*}}, %{{.*}}[0, 6] : vector<3xf32>, vector<4xf32> 182 %3 = vector.shuffle %2, %b[0, 6] : vector<3xf32>, vector<4xf32> 183 return %3 : vector<2xf32> 184} 185 186// CHECK-LABEL: @shuffle2D 187func.func @shuffle2D(%a: vector<1x4xf32>, %b: vector<2x4xf32>) -> vector<3x4xf32> { 188 // CHECK: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 2] : vector<1x4xf32>, vector<2x4xf32> 189 %1 = vector.shuffle %a, %b[0, 1, 2] : vector<1x4xf32>, vector<2x4xf32> 190 return %1 : vector<3x4xf32> 191} 192 193// CHECK-LABEL: @shuffle_poison_mask 194func.func @shuffle_poison_mask(%a: vector<4xf32>, %b: vector<4xf32>) -> vector<4xf32> { 195 // CHECK: vector.shuffle %{{.*}}, %{{.*}}[1, -1, 6, -1] : vector<4xf32>, vector<4xf32> 196 %1 = vector.shuffle %a, %a[1, -1, 6, -1] : vector<4xf32>, vector<4xf32> 197 return %1 : vector<4xf32> 198} 199 200// CHECK-LABEL: @extract_element_0d 201func.func @extract_element_0d(%a: vector<f32>) -> f32 { 202 // CHECK-NEXT: vector.extractelement %{{.*}}[] : vector<f32> 203 %1 = vector.extractelement %a[] : vector<f32> 204 return %1 : f32 205} 206 207// CHECK-LABEL: @extract_element 208func.func @extract_element(%a: vector<16xf32>) -> f32 { 209 // CHECK: %[[C15:.*]] = arith.constant 15 : i32 210 %c = arith.constant 15 : i32 211 // CHECK-NEXT: vector.extractelement %{{.*}}[%[[C15]] : i32] : vector<16xf32> 212 %1 = vector.extractelement %a[%c : i32] : vector<16xf32> 213 return %1 : f32 214} 215 216// CHECK-LABEL: @extract_const_idx 217func.func @extract_const_idx(%arg0: vector<4x8x16xf32>) 218 -> (vector<4x8x16xf32>, vector<8x16xf32>, vector<16xf32>, f32) { 219 // CHECK: vector.extract {{.*}}[] : vector<4x8x16xf32> from vector<4x8x16xf32> 220 %0 = vector.extract %arg0[] : vector<4x8x16xf32> from vector<4x8x16xf32> 221 // CHECK: vector.extract {{.*}}[3] : vector<8x16xf32> from vector<4x8x16xf32> 222 %1 = vector.extract %arg0[3] : vector<8x16xf32> from vector<4x8x16xf32> 223 // CHECK-NEXT: vector.extract {{.*}}[3, 3] : vector<16xf32> from vector<4x8x16xf32> 224 %2 = vector.extract %arg0[3, 3] : vector<16xf32> from vector<4x8x16xf32> 225 // CHECK-NEXT: vector.extract {{.*}}[3, 3, 3] : f32 from vector<4x8x16xf32> 226 %3 = vector.extract %arg0[3, 3, 3] : f32 from vector<4x8x16xf32> 227 return %0, %1, %2, %3 : vector<4x8x16xf32>, vector<8x16xf32>, vector<16xf32>, f32 228} 229 230// CHECK-LABEL: @extract_val_idx 231// CHECK-SAME: %[[VEC:.+]]: vector<4x8x16xf32>, %[[IDX:.+]]: index 232func.func @extract_val_idx(%arg0: vector<4x8x16xf32>, %idx: index) 233 -> (vector<8x16xf32>, vector<16xf32>, f32) { 234 // CHECK: vector.extract %[[VEC]][%[[IDX]]] : vector<8x16xf32> from vector<4x8x16xf32> 235 %0 = vector.extract %arg0[%idx] : vector<8x16xf32> from vector<4x8x16xf32> 236 // CHECK-NEXT: vector.extract %[[VEC]][%[[IDX]], %[[IDX]]] : vector<16xf32> from vector<4x8x16xf32> 237 %1 = vector.extract %arg0[%idx, %idx] : vector<16xf32> from vector<4x8x16xf32> 238 // CHECK-NEXT: vector.extract %[[VEC]][%[[IDX]], 5, %[[IDX]]] : f32 from vector<4x8x16xf32> 239 %2 = vector.extract %arg0[%idx, 5, %idx] : f32 from vector<4x8x16xf32> 240 return %0, %1, %2 : vector<8x16xf32>, vector<16xf32>, f32 241} 242 243// CHECK-LABEL: @extract_0d 244func.func @extract_0d(%a: vector<f32>) -> f32 { 245 // CHECK-NEXT: vector.extract %{{.*}}[] : f32 from vector<f32> 246 %0 = vector.extract %a[] : f32 from vector<f32> 247 return %0 : f32 248} 249 250// CHECK-LABEL: @extract_poison_idx 251func.func @extract_poison_idx(%a: vector<4x5xf32>) -> f32 { 252 // CHECK-NEXT: vector.extract %{{.*}}[-1, 0] : f32 from vector<4x5xf32> 253 %0 = vector.extract %a[-1, 0] : f32 from vector<4x5xf32> 254 return %0 : f32 255} 256 257// CHECK-LABEL: @insert_element_0d 258func.func @insert_element_0d(%a: f32, %b: vector<f32>) -> vector<f32> { 259 // CHECK-NEXT: vector.insertelement %{{.*}}, %{{.*}}[] : vector<f32> 260 %1 = vector.insertelement %a, %b[] : vector<f32> 261 return %1 : vector<f32> 262} 263 264// CHECK-LABEL: @insert_element 265func.func @insert_element(%a: f32, %b: vector<16xf32>) -> vector<16xf32> { 266 // CHECK: %[[C15:.*]] = arith.constant 15 : i32 267 %c = arith.constant 15 : i32 268 // CHECK-NEXT: vector.insertelement %{{.*}}, %{{.*}}[%[[C15]] : i32] : vector<16xf32> 269 %1 = vector.insertelement %a, %b[%c : i32] : vector<16xf32> 270 return %1 : vector<16xf32> 271} 272 273// CHECK-LABEL: @insert_const_idx 274func.func @insert_const_idx(%a: f32, %b: vector<16xf32>, %c: vector<8x16xf32>, 275 %res: vector<4x8x16xf32>) -> vector<4x8x16xf32> { 276 // CHECK: vector.insert %{{.*}}, %{{.*}}[3] : vector<8x16xf32> into vector<4x8x16xf32> 277 %1 = vector.insert %c, %res[3] : vector<8x16xf32> into vector<4x8x16xf32> 278 // CHECK: vector.insert %{{.*}}, %{{.*}}[3, 3] : vector<16xf32> into vector<4x8x16xf32> 279 %2 = vector.insert %b, %res[3, 3] : vector<16xf32> into vector<4x8x16xf32> 280 // CHECK: vector.insert %{{.*}}, %{{.*}}[3, 3, 3] : f32 into vector<4x8x16xf32> 281 %3 = vector.insert %a, %res[3, 3, 3] : f32 into vector<4x8x16xf32> 282 // CHECK: vector.insert %{{.*}}, %{{.*}}[] : vector<4x8x16xf32> into vector<4x8x16xf32> 283 %4 = vector.insert %3, %3[] : vector<4x8x16xf32> into vector<4x8x16xf32> 284 return %4 : vector<4x8x16xf32> 285} 286 287// CHECK-LABEL: @insert_val_idx 288// CHECK-SAME: %[[A:.+]]: f32, %[[B:.+]]: vector<16xf32>, %[[C:.+]]: vector<8x16xf32>, %[[IDX:.+]]: index 289func.func @insert_val_idx(%a: f32, %b: vector<16xf32>, %c: vector<8x16xf32>, 290 %idx: index, %res: vector<4x8x16xf32>) -> vector<4x8x16xf32> { 291 // CHECK: vector.insert %[[C]], %{{.*}}[%[[IDX]]] : vector<8x16xf32> into vector<4x8x16xf32> 292 %0 = vector.insert %c, %res[%idx] : vector<8x16xf32> into vector<4x8x16xf32> 293 // CHECK: vector.insert %[[B]], %{{.*}}[%[[IDX]], %[[IDX]]] : vector<16xf32> into vector<4x8x16xf32> 294 %1 = vector.insert %b, %res[%idx, %idx] : vector<16xf32> into vector<4x8x16xf32> 295 // CHECK: vector.insert %[[A]], %{{.*}}[%[[IDX]], 5, %[[IDX]]] : f32 into vector<4x8x16xf32> 296 %2 = vector.insert %a, %res[%idx, 5, %idx] : f32 into vector<4x8x16xf32> 297 return %2 : vector<4x8x16xf32> 298} 299 300// CHECK-LABEL: @insert_0d 301func.func @insert_0d(%a: f32, %b: vector<f32>, %c: vector<2x3xf32>) -> (vector<f32>, vector<2x3xf32>) { 302 // CHECK-NEXT: vector.insert %{{.*}}, %{{.*}}[] : f32 into vector<f32> 303 %1 = vector.insert %a, %b[] : f32 into vector<f32> 304 // CHECK-NEXT: vector.insert %{{.*}}, %{{.*}}[0, 1] : vector<f32> into vector<2x3xf32> 305 %2 = vector.insert %b, %c[0, 1] : vector<f32> into vector<2x3xf32> 306 return %1, %2 : vector<f32>, vector<2x3xf32> 307} 308 309// CHECK-LABEL: @insert_poison_idx 310func.func @insert_poison_idx(%a: vector<4x5xf32>, %b: f32) { 311 // CHECK-NEXT: vector.insert %{{.*}}, %{{.*}}[-1, 0] : f32 into vector<4x5xf32> 312 vector.insert %b, %a[-1, 0] : f32 into vector<4x5xf32> 313 return 314} 315 316// CHECK-LABEL: @outerproduct 317func.func @outerproduct(%arg0: vector<4xf32>, %arg1: vector<8xf32>, %arg2: vector<4x8xf32>) -> vector<4x8xf32> { 318 // CHECK: vector.outerproduct {{.*}} : vector<4xf32>, vector<8xf32> 319 %0 = vector.outerproduct %arg0, %arg1 : vector<4xf32>, vector<8xf32> 320 // CHECK: vector.outerproduct {{.*}}, {{.*}}, {{.*}} : vector<4xf32>, vector<8xf32> 321 %1 = vector.outerproduct %arg0, %arg1, %arg2 : vector<4xf32>, vector<8xf32> 322 return %1 : vector<4x8xf32> 323} 324 325// CHECK-LABEL: @outerproduct_scalable 326func.func @outerproduct_scalable(%arg0 : vector<[4]xf32>, %arg1 : vector<[8]xf32>) { 327 // CHECK: vector.outerproduct {{.*}} : vector<[4]xf32>, vector<[8]xf32> 328 %0 = vector.outerproduct %arg0, %arg1 : vector<[4]xf32>, vector<[8]xf32> 329 330 %cst = arith.constant 1.0 : f32 331 // CHECK: vector.outerproduct {{.*}} : vector<[4]xf32>, f32 332 %1 = vector.outerproduct %arg0, %cst : vector<[4]xf32>, f32 333 return 334} 335 336// CHECK-LABEL: @insert_strided_slice 337func.func @insert_strided_slice(%a: vector<4x4xf32>, %b: vector<4x8x16xf32>) { 338 // CHECK: vector.insert_strided_slice %{{.*}}, %{{.*}} {offsets = [2, 2, 2], strides = [1, 1]} : vector<4x4xf32> into vector<4x8x16xf32> 339 %1 = vector.insert_strided_slice %a, %b {offsets = [2, 2, 2], strides = [1, 1]} : vector<4x4xf32> into vector<4x8x16xf32> 340 return 341} 342 343// CHECK-LABEL: @insert_strided_slice_scalable 344func.func @insert_strided_slice_scalable(%a: vector<4x[16]xf32>, %b: vector<4x8x[16]xf32>) { 345 // CHECK: vector.insert_strided_slice %{{.*}}, %{{.*}} {offsets = [2, 2, 0], strides = [1, 1]} : vector<4x[16]xf32> into vector<4x8x[16]xf32> 346 %1 = vector.insert_strided_slice %a, %b {offsets = [2, 2, 0], strides = [1, 1]} : vector<4x[16]xf32> into vector<4x8x[16]xf32> 347 return 348} 349 350// CHECK-LABEL: @extract_strided_slice 351func.func @extract_strided_slice(%arg0: vector<4x8x16xf32>) -> vector<2x2x16xf32> { 352 // CHECK: vector.extract_strided_slice %{{.*}} {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8x16xf32> 353 %1 = vector.extract_strided_slice %arg0 {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8x16xf32> to vector<2x2x16xf32> 354 return %1: vector<2x2x16xf32> 355} 356 357// CHECK-LABEL: @extract_strided_slice_scalable 358func.func @extract_strided_slice_scalable(%arg0: vector<4x[8]x16xf32>) -> vector<2x[8]x16xf32> { 359 // CHECK: vector.extract_strided_slice %{{.*}} {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x[8]x16xf32> 360 %1 = vector.extract_strided_slice %arg0 {offsets = [2, 0], sizes = [2, 8], strides = [1, 1]} : vector<4x[8]x16xf32> to vector<2x[8]x16xf32> 361 return %1: vector<2x[8]x16xf32> 362} 363 364#contraction_to_scalar_accesses = [ 365 affine_map<(i) -> (i)>, 366 affine_map<(i) -> (i)>, 367 affine_map<(i) -> ()> 368] 369#contraction_to_scalar_trait = { 370 indexing_maps = #contraction_to_scalar_accesses, 371 iterator_types = ["reduction"] 372} 373// CHECK-LABEL: @contraction_to_scalar 374func.func @contraction_to_scalar(%arg0: vector<10xf32>, %arg1: vector<10xf32>) -> f32 { 375 // CHECK: %[[C0:.*]] = arith.constant 0.000000e+00 : f32 376 %f0 = arith.constant 0.0: f32 377 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["reduction"], kind = #vector.kind<add>} %{{.*}}, %{{.*}}, %[[C0]] : vector<10xf32>, vector<10xf32> into f32 378 %0 = vector.contract #contraction_to_scalar_trait %arg0, %arg1, %f0 379 : vector<10xf32>, vector<10xf32> into f32 380 // CHECK: return %[[X]] : f32 381 return %0 : f32 382} 383 384// CHECK-LABEL: @contraction_to_scalar_scalable 385func.func @contraction_to_scalar_scalable(%arg0: vector<[10]xf32>, %arg1: vector<[10]xf32>) -> f32 { 386 // CHECK: %[[C0:.*]] = arith.constant 0.000000e+00 : f32 387 %f0 = arith.constant 0.0: f32 388 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["reduction"], kind = #vector.kind<add>} %{{.*}}, %{{.*}}, %[[C0]] : vector<[10]xf32>, vector<[10]xf32> into f32 389 %0 = vector.contract #contraction_to_scalar_trait %arg0, %arg1, %f0 390 : vector<[10]xf32>, vector<[10]xf32> into f32 391 // CHECK: return %[[X]] : f32 392 return %0 : f32 393} 394 395// CHECK-LABEL: @contraction_extra_attrs 396func.func @contraction_extra_attrs(%arg0: vector<10xf32>, %arg1: vector<10xf32>) -> f32 { 397 // CHECK: %[[C0:.*]] = arith.constant 0.000000e+00 : f32 398 %f0 = arith.constant 0.0: f32 399 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["reduction"], kind = #vector.kind<add>} %{{.*}}, %{{.*}}, %[[C0]] {first_attr = 1 : i32, second_attr = "string"} : vector<10xf32>, vector<10xf32> into f32 400 %0 = vector.contract #contraction_to_scalar_trait %arg0, %arg1, %f0 401 {first_attr = 1 : i32, second_attr = "string"} 402 : vector<10xf32>, vector<10xf32> into f32 403 // CHECK: return %[[X]] : f32 404 return %0 : f32 405} 406 407#contraction_to_scalar_max_accesses = [ 408 affine_map<(i) -> (i)>, 409 affine_map<(i) -> (i)>, 410 affine_map<(i) -> ()> 411] 412#contraction_to_scalar_max_trait = { 413 indexing_maps = #contraction_to_scalar_max_accesses, 414 iterator_types = ["reduction"], 415 kind = #vector.kind<maxnumf> 416} 417// CHECK-LABEL: @contraction_to_scalar_with_max 418func.func @contraction_to_scalar_with_max(%arg0: vector<10xf32>, %arg1: vector<10xf32>) -> f32 { 419 // CHECK: %[[C0:.*]] = arith.constant 0.000000e+00 : f32 420 %f0 = arith.constant 0.0: f32 421 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["reduction"], kind = #vector.kind<maxnumf>} %{{.*}}, %{{.*}}, %[[C0]] : vector<10xf32>, vector<10xf32> into f32 422 %0 = vector.contract #contraction_to_scalar_max_trait %arg0, %arg1, %f0 423 : vector<10xf32>, vector<10xf32> into f32 424 // CHECK: return %[[X]] : f32 425 return %0 : f32 426} 427 428#contraction_accesses0 = [ 429 affine_map<(b0, f0, f1, c0, c1) -> (c0, b0, c1, f0)>, 430 affine_map<(b0, f0, f1, c0, c1) -> (b0, c1, c0, f1)>, 431 affine_map<(b0, f0, f1, c0, c1) -> (b0, f0, f1)> 432] 433#contraction_trait0 = { 434 indexing_maps = #contraction_accesses0, 435 iterator_types = ["parallel", "parallel", "parallel", "reduction", "reduction"] 436} 437#contraction_accesses1 = [ // 7, 8, 16, 15 438 affine_map<(f0, f1, f2, f3, c0, c1) -> (c0, f0, c1, f2)>, 439 // 8, 16, 7, 5 440 affine_map<(f0, f1, f2, f3, c0, c1) -> (f1, c1, c0, f3)>, 441 // 8, 8, 15, 5 442 affine_map<(f0, f1, f2, f3, c0, c1) -> (f0, f1, f2, f3)> 443] 444#iterator_types1 = ["parallel", "parallel", "parallel", "parallel", "reduction", 445 "reduction"] 446#contraction_trait1 = { 447 indexing_maps = #contraction_accesses1, 448 iterator_types = #iterator_types1 449} 450#contraction_trait2 = { 451 indexing_maps = #contraction_accesses1, 452 iterator_types = #iterator_types1, 453 kind = #vector.kind<maxnumf> 454} 455// CHECK-LABEL: @contraction 456func.func @contraction(%arg0 : vector<7x8x16x15xf32>, %arg1 : vector<8x16x7x5xf32>, 457 %arg2 : vector<8x15x5xf32>, %arg3 : vector<8x8x15x5xf32>, 458 %arg4 : vector<7x8x16x15xf16>, %arg5 : vector<8x16x7x5xf16>) { 459 // Test contraction with batch and contracting dims. 460 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x15x5xf32> 461 %0 = vector.contract #contraction_trait0 %arg0, %arg1, %arg2 462 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x15x5xf32> 463 // Test contraction with only contracting dims. In this case the lhs/rhs 464 // dimension of size 8 will be considered a parallel dim for lhs/rhs and will 465 // appear twice in the output. 466 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 467 %1 = vector.contract #contraction_trait1 %arg0, %arg1, %arg3 468 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 469 // Test contraction with mixed type. 470 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf16>, vector<8x16x7x5xf16> into vector<8x8x15x5xf32> 471 %3 = vector.contract #contraction_trait1 %arg4, %arg5, %arg3 472 : vector<7x8x16x15xf16>, vector<8x16x7x5xf16> into vector<8x8x15x5xf32> 473 // Test contraction with "max" instead of "add". 474 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<maxnumf>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 475 %4 = vector.contract #contraction_trait2 %arg0, %arg1, %arg3 476 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 477 return 478} 479 480#contraction_matmul_accesses = [ 481 affine_map<(d0, d1, d2) -> (d0, d2)>, 482 affine_map<(d0, d1, d2) -> (d2, d1)>, 483 affine_map<(d0, d1, d2) -> (d0, d1)> 484] 485#contraction_matmul_trait = { 486 indexing_maps = #contraction_matmul_accesses, 487 iterator_types = ["parallel", "parallel", "reduction"] 488} 489// CHECK-LABEL: @contraction_matmul_scalable 490func.func @contraction_matmul_scalable(%A: vector<8x1xf32>, %B: vector<1x[32]xf32>, %C: vector<8x[32]xf32>) -> vector<8x[32]xf32> { 491 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<8x1xf32>, vector<1x[32]xf32> into vector<8x[32]xf32> 492 %res = vector.contract #contraction_matmul_trait %A, %B, %C 493 : vector<8x1xf32>, vector<1x[32]xf32> into vector<8x[32]xf32> 494 // CHECK: return %[[X]] : vector<8x[32]xf32> 495 return %res : vector<8x[32]xf32> 496} 497 498// CHECK-LABEL: @create_vector_mask 499func.func @create_vector_mask() { 500 // CHECK: %[[C2:.*]] = arith.constant 2 : index 501 %c2 = arith.constant 2 : index 502 // CHECK-NEXT: %[[C3:.*]] = arith.constant 3 : index 503 %c3 = arith.constant 3 : index 504 // CHECK-NEXT: vector.create_mask %[[C3]], %[[C2]] : vector<4x3xi1> 505 %0 = vector.create_mask %c3, %c2 : vector<4x3xi1> 506 507 return 508} 509 510// CHECK-LABEL: @constant_vector_mask_0d 511func.func @constant_vector_mask_0d() { 512 // CHECK: vector.constant_mask [0] : vector<i1> 513 %0 = vector.constant_mask [0] : vector<i1> 514 // CHECK: vector.constant_mask [1] : vector<i1> 515 %1 = vector.constant_mask [1] : vector<i1> 516 return 517} 518 519// CHECK-LABEL: @constant_vector_mask 520func.func @constant_vector_mask() { 521 // CHECK: vector.constant_mask [3, 2] : vector<4x3xi1> 522 %0 = vector.constant_mask [3, 2] : vector<4x3xi1> 523 // CHECK: vector.constant_mask [0] : vector<[4]xi1> 524 %1 = vector.constant_mask [0] : vector<[4]xi1> 525 // CHECK: vector.constant_mask [4] : vector<[4]xi1> 526 %2 = vector.constant_mask [4] : vector<[4]xi1> 527 // CHECK: vector.constant_mask [1, 4] : vector<2x[4]xi1> 528 %3 = vector.constant_mask [1, 4] : vector<2x[4]xi1> 529 return 530} 531 532// CHECK-LABEL: @vector_print_on_vector 533func.func @vector_print_on_vector(%arg0: vector<8x4xf32>) { 534 // CHECK: vector.print %{{.*}} : vector<8x4xf32> 535 vector.print %arg0 : vector<8x4xf32> 536 return 537} 538 539// CHECK-LABEL: @vector_print_on_scalar 540func.func @vector_print_on_scalar(%arg0: i64) { 541 // CHECK: vector.print %{{.*}} : i64 542 vector.print %arg0 : i64 543 return 544} 545 546// CHECK-LABEL: @shape_cast 547func.func @shape_cast(%arg0 : vector<5x1x3x2xf32>, 548 %arg1 : vector<8x1xf32>, 549 %arg2 : vector<16x1x1xf32>) 550 -> (vector<15x2xf32>, vector<8xf32>, vector<16xf32>, vector<16x1xf32>) { 551 552 // CHECK: vector.shape_cast %{{.*}} : vector<5x1x3x2xf32> to vector<15x2xf32> 553 %0 = vector.shape_cast %arg0 : vector<5x1x3x2xf32> to vector<15x2xf32> 554 555 // CHECK-NEXT: vector.shape_cast %{{.*}} : vector<8x1xf32> to vector<8xf32> 556 %1 = vector.shape_cast %arg1 : vector<8x1xf32> to vector<8xf32> 557 558 // CHECK-NEXT: vector.shape_cast %{{.*}} : vector<16x1x1xf32> to vector<16xf32> 559 %2 = vector.shape_cast %arg2 : vector<16x1x1xf32> to vector<16xf32> 560 561 // CHECK-NEXT: vector.shape_cast %{{.*}} : vector<16x1x1xf32> to vector<16x1xf32> 562 %3 = vector.shape_cast %arg2 : vector<16x1x1xf32> to vector<16x1xf32> 563 564 return %0, %1, %2, %3 : vector<15x2xf32>, vector<8xf32>, vector<16xf32>, vector<16x1xf32> 565} 566 567// CHECK-LABEL: @shape_cast_0d 568func.func @shape_cast_0d(%arg0 : vector<1x1x1x1xf32>) -> (vector<1x1x1x1xf32>) { 569 570 // CHECK: vector.shape_cast %{{.*}} : vector<1x1x1x1xf32> to vector<f32> 571 %0 = vector.shape_cast %arg0 : vector<1x1x1x1xf32> to vector<f32> 572 573 // CHECK: vector.shape_cast %{{.*}} : vector<f32> to vector<1x1x1x1xf32> 574 %1 = vector.shape_cast %0 : vector<f32> to vector<1x1x1x1xf32> 575 576 return %1 : vector<1x1x1x1xf32> 577} 578 579// CHECK-LABEL: @bitcast 580func.func @bitcast(%arg0 : vector<5x1x3x2xf32>, 581 %arg1 : vector<8x1xi32>, 582 %arg2 : vector<16x1x8xi8>, 583 %arg3 : vector<8x2x1xindex>, 584 %arg4 : vector<f32>) 585 -> (vector<5x1x3x4xf16>, vector<5x1x3x8xi8>, vector<8x4xi8>, vector<8x1xf32>, vector<16x1x2xi32>, vector<16x1x4xi16>, vector<16x1x1xindex>, vector<8x2x2xf32>, vector<i32>) { 586 587 // CHECK: vector.bitcast %{{.*}} : vector<5x1x3x2xf32> to vector<5x1x3x4xf16> 588 %0 = vector.bitcast %arg0 : vector<5x1x3x2xf32> to vector<5x1x3x4xf16> 589 590 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<5x1x3x2xf32> to vector<5x1x3x8xi8> 591 %1 = vector.bitcast %arg0 : vector<5x1x3x2xf32> to vector<5x1x3x8xi8> 592 593 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<8x1xi32> to vector<8x4xi8> 594 %2 = vector.bitcast %arg1 : vector<8x1xi32> to vector<8x4xi8> 595 596 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<8x1xi32> to vector<8x1xf32> 597 %3 = vector.bitcast %arg1 : vector<8x1xi32> to vector<8x1xf32> 598 599 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<16x1x8xi8> to vector<16x1x2xi32> 600 %4 = vector.bitcast %arg2 : vector<16x1x8xi8> to vector<16x1x2xi32> 601 602 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<16x1x8xi8> to vector<16x1x4xi16> 603 %5 = vector.bitcast %arg2 : vector<16x1x8xi8> to vector<16x1x4xi16> 604 605 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<16x1x8xi8> to vector<16x1x1xindex> 606 %6 = vector.bitcast %arg2 : vector<16x1x8xi8> to vector<16x1x1xindex> 607 608 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<8x2x1xindex> to vector<8x2x2xf32> 609 %7 = vector.bitcast %arg3 : vector<8x2x1xindex> to vector<8x2x2xf32> 610 611 // CHECK: vector.bitcast %{{.*}} : vector<f32> to vector<i32> 612 %8 = vector.bitcast %arg4 : vector<f32> to vector<i32> 613 614 return %0, %1, %2, %3, %4, %5, %6, %7, %8 : vector<5x1x3x4xf16>, vector<5x1x3x8xi8>, vector<8x4xi8>, vector<8x1xf32>, vector<16x1x2xi32>, vector<16x1x4xi16>, vector<16x1x1xindex>, vector<8x2x2xf32>, vector<i32> 615} 616 617// CHECK-LABEL: @vector_fma 618func.func @vector_fma(%a: vector<8xf32>, %b: vector<8x4xf32>, %c: vector<f32>) { 619 // CHECK: vector.fma %{{.*}} : vector<8xf32> 620 vector.fma %a, %a, %a : vector<8xf32> 621 // CHECK: vector.fma %{{.*}} : vector<8x4xf32> 622 vector.fma %b, %b, %b : vector<8x4xf32> 623 // CHECK: vector.fma %{{.*}} : vector<f32> 624 vector.fma %c, %c, %c : vector<f32> 625 return 626} 627 628// CHECK-LABEL: @reduce_fp 629func.func @reduce_fp(%arg0: vector<16xf32>, %arg1: f32) -> f32 { 630 // CHECK: vector.reduction <add>, %{{.*}} : vector<16xf32> into f32 631 vector.reduction <add>, %arg0 : vector<16xf32> into f32 632 // CHECK: vector.reduction <add>, %{{.*}}, %{{.*}} : vector<16xf32> into f32 633 vector.reduction <add>, %arg0, %arg1 : vector<16xf32> into f32 634 // CHECK: vector.reduction <mul>, %{{.*}} : vector<16xf32> into f32 635 vector.reduction <mul>, %arg0 : vector<16xf32> into f32 636 // CHECK: vector.reduction <mul>, %{{.*}}, %{{.*}} : vector<16xf32> into f32 637 vector.reduction <mul>, %arg0, %arg1 : vector<16xf32> into f32 638 // CHECK: vector.reduction <minnumf>, %{{.*}} : vector<16xf32> into f32 639 vector.reduction <minnumf>, %arg0 : vector<16xf32> into f32 640 // CHECK: %[[X0:.*]] = vector.reduction <maxnumf>, %{{.*}} : vector<16xf32> into f32 641 %0 = vector.reduction <maxnumf>, %arg0 : vector<16xf32> into f32 642 // CHECK: vector.reduction <minimumf>, %{{.*}} : vector<16xf32> into f32 643 vector.reduction <minimumf>, %arg0 : vector<16xf32> into f32 644 // CHECK: %[[X1:.*]] = vector.reduction <maximumf>, %{{.*}} : vector<16xf32> into f32 645 %1 = vector.reduction <maximumf>, %arg0 : vector<16xf32> into f32 646 // CHECK: return %[[X0]] : f32 647 return %0 : f32 648} 649 650// CHECK-LABEL: @reduce_int 651func.func @reduce_int(%arg0: vector<16xi32>) -> i32 { 652 // CHECK: vector.reduction <add>, %{{.*}} : vector<16xi32> into i32 653 vector.reduction <add>, %arg0 : vector<16xi32> into i32 654 // CHECK: vector.reduction <mul>, %{{.*}} : vector<16xi32> into i32 655 vector.reduction <mul>, %arg0 : vector<16xi32> into i32 656 // CHECK: vector.reduction <minui>, %{{.*}} : vector<16xi32> into i32 657 vector.reduction <minui>, %arg0 : vector<16xi32> into i32 658 // CHECK: vector.reduction <minsi>, %{{.*}} : vector<16xi32> into i32 659 vector.reduction <minsi>, %arg0 : vector<16xi32> into i32 660 // CHECK: vector.reduction <maxui>, %{{.*}} : vector<16xi32> into i32 661 vector.reduction <maxui>, %arg0 : vector<16xi32> into i32 662 // CHECK: vector.reduction <maxsi>, %{{.*}} : vector<16xi32> into i32 663 vector.reduction <maxsi>, %arg0 : vector<16xi32> into i32 664 // CHECK: vector.reduction <and>, %{{.*}} : vector<16xi32> into i32 665 vector.reduction <and>, %arg0 : vector<16xi32> into i32 666 // CHECK: vector.reduction <or>, %{{.*}} : vector<16xi32> into i32 667 vector.reduction <or>, %arg0 : vector<16xi32> into i32 668 // CHECK: %[[X:.*]] = vector.reduction <xor>, %{{.*}} : vector<16xi32> into i32 669 %0 = vector.reduction <xor>, %arg0 : vector<16xi32> into i32 670 // CHECK: return %[[X]] : i32 671 return %0 : i32 672} 673 674// CHECK-LABEL: @reduce_int 675func.func @reduce_int_0d(%arg0: vector<i32>) -> i32 { 676 // CHECK: vector.reduction <add>, %{{.*}} : vector<i32> into i32 677 vector.reduction <add>, %arg0 : vector<i32> into i32 678 // CHECK: vector.reduction <mul>, %{{.*}} : vector<i32> into i32 679 vector.reduction <mul>, %arg0 : vector<i32> into i32 680 // CHECK: vector.reduction <minui>, %{{.*}} : vector<i32> into i32 681 vector.reduction <minui>, %arg0 : vector<i32> into i32 682 // CHECK: vector.reduction <minsi>, %{{.*}} : vector<i32> into i32 683 vector.reduction <minsi>, %arg0 : vector<i32> into i32 684 // CHECK: vector.reduction <maxui>, %{{.*}} : vector<i32> into i32 685 vector.reduction <maxui>, %arg0 : vector<i32> into i32 686 // CHECK: vector.reduction <maxsi>, %{{.*}} : vector<i32> into i32 687 vector.reduction <maxsi>, %arg0 : vector<i32> into i32 688 // CHECK: vector.reduction <and>, %{{.*}} : vector<i32> into i32 689 vector.reduction <and>, %arg0 : vector<i32> into i32 690 // CHECK: vector.reduction <or>, %{{.*}} : vector<i32> into i32 691 vector.reduction <or>, %arg0 : vector<i32> into i32 692 // CHECK: %[[X:.*]] = vector.reduction <xor>, %{{.*}} : vector<i32> into i32 693 %0 = vector.reduction <xor>, %arg0 : vector<i32> into i32 694 // CHECK: return %[[X]] : i32 695 return %0 : i32 696} 697 698// CHECK-LABEL: @transpose_fp 699func.func @transpose_fp(%arg0: vector<3x7xf32>) -> vector<7x3xf32> { 700 // CHECK: %[[X:.*]] = vector.transpose %{{.*}}, [1, 0] : vector<3x7xf32> to vector<7x3xf32> 701 %0 = vector.transpose %arg0, [1, 0] : vector<3x7xf32> to vector<7x3xf32> 702 // CHECK: return %[[X]] : vector<7x3xf32> 703 return %0 : vector<7x3xf32> 704} 705 706// CHECK-LABEL: @transpose_int 707func.func @transpose_int(%arg0: vector<11x7x3x2xi32>) -> vector<2x11x7x3xi32> { 708 // CHECK: %[[X:.*]] = vector.transpose %{{.*}}, [3, 0, 1, 2] : vector<11x7x3x2xi32> to vector<2x11x7x3xi32> 709 %0 = vector.transpose %arg0, [3, 0, 1, 2] : vector<11x7x3x2xi32> to vector<2x11x7x3xi32> 710 // CHECK: return %[[X]] : vector<2x11x7x3xi32> 711 return %0 : vector<2x11x7x3xi32> 712} 713 714// CHECK-LABEL: @transpose_fp_0d 715func.func @transpose_fp_0d(%arg0: vector<f32>) -> vector<f32> { 716 // CHECK: %[[X:.*]] = vector.transpose %{{.*}}, [] : vector<f32> to vector<f32> 717 %0 = vector.transpose %arg0, [] : vector<f32> to vector<f32> 718 // CHECK: return %[[X]] : vector<f32> 719 return %0 : vector<f32> 720} 721 722// CHECK-LABEL: @transpose_int_0d 723func.func @transpose_int_0d(%arg0: vector<i32>) -> vector<i32> { 724 // CHECK: %[[X:.*]] = vector.transpose %{{.*}}, [] : vector<i32> to vector<i32> 725 %0 = vector.transpose %arg0, [] : vector<i32> to vector<i32> 726 // CHECK: return %[[X]] : vector<i32> 727 return %0 : vector<i32> 728} 729 730// CHECK-LABEL: @flat_transpose_fp 731func.func @flat_transpose_fp(%arg0: vector<16xf32>) -> vector<16xf32> { 732 // CHECK: %[[X:.*]] = vector.flat_transpose %{{.*}} {columns = 4 : i32, rows = 4 : i32} : vector<16xf32> -> vector<16xf32> 733 %0 = vector.flat_transpose %arg0 { rows = 4: i32, columns = 4: i32 } : vector<16xf32> -> vector<16xf32> 734 // CHECK: return %[[X]] : vector<16xf32> 735 return %0 : vector<16xf32> 736} 737 738// CHECK-LABEL: @flat_transpose_int 739func.func @flat_transpose_int(%arg0: vector<16xi32>) -> vector<16xi32> { 740 // CHECK: %[[X:.*]] = vector.flat_transpose %{{.*}} {columns = 8 : i32, rows = 2 : i32} : vector<16xi32> -> vector<16xi32> 741 %0 = vector.flat_transpose %arg0 { rows = 2: i32, columns = 8: i32 } : vector<16xi32> -> vector<16xi32> 742 // CHECK: return %[[X]] : vector<16xi32> 743 return %0 : vector<16xi32> 744} 745 746// CHECK-LABEL: @vector_load_and_store_0d_scalar_memref 747func.func @vector_load_and_store_0d_scalar_memref(%memref : memref<200x100xf32>, 748 %i : index, %j : index) { 749 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<f32> 750 %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<f32> 751 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<f32> 752 vector.store %0, %memref[%i, %j] : memref<200x100xf32>, vector<f32> 753 return 754} 755 756// CHECK-LABEL: @vector_load_and_store_0d_scalar_strided_memref 757func.func @vector_load_and_store_0d_scalar_strided_memref(%memref : memref<200x100xf32, strided<[?, ?], offset: ?>>, 758 %i : index, %j : index) { 759 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<f32> 760 %0 = vector.load %memref[%i, %j] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<f32> 761 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<f32> 762 vector.store %0, %memref[%i, %j] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<f32> 763 return 764} 765 766// CHECK-LABEL: @vector_load_and_store_unit_vec_strided_memref 767func.func @vector_load_and_store_unit_vec_strided_memref(%memref : memref<200x100xf32, strided<[?, ?], offset: ?>>, 768 %i : index, %j : index) { 769 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<1xf32> 770 %0 = vector.load %memref[%i, %j] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<1xf32> 771 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<1xf32> 772 vector.store %0, %memref[%i, %j] : memref<200x100xf32, strided<[?, ?], offset: ?>>, vector<1xf32> 773 return 774} 775 776// CHECK-LABEL: @vector_load_and_store_1d_scalar_memref 777func.func @vector_load_and_store_1d_scalar_memref(%memref : memref<200x100xf32>, 778 %i : index, %j : index) { 779 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<8xf32> 780 %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<8xf32> 781 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<8xf32> 782 vector.store %0, %memref[%i, %j] : memref<200x100xf32>, vector<8xf32> 783 return 784} 785 786// CHECK-LABEL: @vector_load_and_store_1d_vector_memref 787func.func @vector_load_and_store_1d_vector_memref(%memref : memref<200x100xvector<8xf32>>, 788 %i : index, %j : index) { 789 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xvector<8xf32>>, vector<8xf32> 790 %0 = vector.load %memref[%i, %j] : memref<200x100xvector<8xf32>>, vector<8xf32> 791 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xvector<8xf32>>, vector<8xf32> 792 vector.store %0, %memref[%i, %j] : memref<200x100xvector<8xf32>>, vector<8xf32> 793 return 794} 795 796// CHECK-LABEL: @vector_load_and_store_scalable_vector_memref 797func.func @vector_load_and_store_scalable_vector_memref(%v: vector<[4]xi32>, %m: memref<?xi32>) -> vector<[4]xi32> { 798 %c0 = arith.constant 0 : index 799 // CHECK: vector.load {{.*}}: memref<?xi32>, vector<[4]xi32> 800 %0 = vector.load %m[%c0] : memref<?xi32>, vector<[4]xi32> 801 // CHECK: vector.store {{.*}}: memref<?xi32>, vector<[4]xi32> 802 vector.store %v, %m[%c0] : memref<?xi32>, vector<[4]xi32> 803 return %0 : vector<[4]xi32> 804} 805 806func.func @vector_load_and_store_1d_scalable_vector_memref(%memref : memref<200x100xvector<8xf32>>, 807 %i : index, %j : index) { 808 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xvector<8xf32>>, vector<8xf32> 809 %0 = vector.load %memref[%i, %j] : memref<200x100xvector<8xf32>>, vector<8xf32> 810 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xvector<8xf32>>, vector<8xf32> 811 vector.store %0, %memref[%i, %j] : memref<200x100xvector<8xf32>>, vector<8xf32> 812 return 813} 814 815// CHECK-LABEL: @vector_load_and_store_out_of_bounds 816func.func @vector_load_and_store_out_of_bounds(%memref : memref<7xf32>) { 817 %c0 = arith.constant 0 : index 818 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<7xf32>, vector<8xf32> 819 %0 = vector.load %memref[%c0] : memref<7xf32>, vector<8xf32> 820 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<7xf32>, vector<8xf32> 821 vector.store %0, %memref[%c0] : memref<7xf32>, vector<8xf32> 822 return 823} 824 825// CHECK-LABEL: @vector_load_and_store_2d_scalar_memref 826func.func @vector_load_and_store_2d_scalar_memref(%memref : memref<200x100xf32>, 827 %i : index, %j : index) { 828 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<4x8xf32> 829 %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<4x8xf32> 830 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<4x8xf32> 831 vector.store %0, %memref[%i, %j] : memref<200x100xf32>, vector<4x8xf32> 832 return 833} 834 835// CHECK-LABEL: @vector_load_and_store_2d_vector_memref 836func.func @vector_load_and_store_2d_vector_memref(%memref : memref<200x100xvector<4x8xf32>>, 837 %i : index, %j : index) { 838 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 839 %0 = vector.load %memref[%i, %j] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 840 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 841 vector.store %0, %memref[%i, %j] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 842 return 843} 844 845// CHECK-LABEL: @masked_load_and_store 846func.func @masked_load_and_store(%base: memref<?xf32>, %mask: vector<16xi1>, %passthru: vector<16xf32>) { 847 %c0 = arith.constant 0 : index 848 // CHECK: %[[X:.*]] = vector.maskedload %{{.*}}[%{{.*}}], %{{.*}}, %{{.*}} : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 849 %0 = vector.maskedload %base[%c0], %mask, %passthru : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 850 // CHECK: vector.maskedstore %{{.*}}[%{{.*}}], %{{.*}}, %[[X]] : memref<?xf32>, vector<16xi1>, vector<16xf32> 851 vector.maskedstore %base[%c0], %mask, %0 : memref<?xf32>, vector<16xi1>, vector<16xf32> 852 return 853} 854 855// CHECK-LABEL: @masked_load_and_store2d 856func.func @masked_load_and_store2d(%base: memref<?x?xf32>, %mask: vector<16xi1>, %passthru: vector<16xf32>) { 857 %c0 = arith.constant 0 : index 858 // CHECK: %[[X:.*]] = vector.maskedload %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}}, %{{.*}} : memref<?x?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 859 %0 = vector.maskedload %base[%c0, %c0], %mask, %passthru : memref<?x?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 860 // CHECK: vector.maskedstore %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}}, %[[X]] : memref<?x?xf32>, vector<16xi1>, vector<16xf32> 861 vector.maskedstore %base[%c0, %c0], %mask, %0 : memref<?x?xf32>, vector<16xi1>, vector<16xf32> 862 return 863} 864 865// CHECK-LABEL: @gather_and_scatter 866func.func @gather_and_scatter(%base: memref<?xf32>, %v: vector<16xi32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) { 867 %c0 = arith.constant 0 : index 868 // CHECK: %[[X:.*]] = vector.gather %{{.*}}[%{{.*}}] [%{{.*}}], %{{.*}}, %{{.*}} : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 869 %0 = vector.gather %base[%c0][%v], %mask, %pass_thru : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 870 // CHECK: vector.scatter %{{.*}}[%{{.*}}] [%{{.*}}], %{{.*}}, %[[X]] : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> 871 vector.scatter %base[%c0][%v], %mask, %0 : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> 872 return 873} 874 875// CHECK-LABEL: @gather_and_scatter2d 876func.func @gather_and_scatter2d(%base: memref<?x?xf32>, %v: vector<16xi32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) { 877 %c0 = arith.constant 0 : index 878 // CHECK: %[[X:.*]] = vector.gather %{{.*}}[%{{.*}}, %{{.*}}] [%{{.*}}], %{{.*}}, %{{.*}} : memref<?x?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 879 %0 = vector.gather %base[%c0, %c0][%v], %mask, %pass_thru : memref<?x?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 880 // CHECK: vector.scatter %{{.*}}[%{{.*}}] [%{{.*}}], %{{.*}}, %[[X]] : memref<?x?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> 881 vector.scatter %base[%c0, %c0][%v], %mask, %0 : memref<?x?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> 882 return 883} 884 885// CHECK-LABEL: @gather_on_tensor 886func.func @gather_on_tensor(%base: tensor<?xf32>, %v: vector<16xi32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) -> vector<16xf32> { 887 %c0 = arith.constant 0 : index 888 // CHECK: vector.gather %{{.*}}[%{{.*}}] [%{{.*}}], %{{.*}}, %{{.*}} : tensor<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 889 %0 = vector.gather %base[%c0][%v], %mask, %pass_thru : tensor<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 890 return %0 : vector<16xf32> 891} 892 893// CHECK-LABEL: @gather_multi_dims 894func.func @gather_multi_dims(%base: tensor<?xf32>, %v: vector<2x16xi32>, %mask: vector<2x16xi1>, %pass_thru: vector<2x16xf32>) -> vector<2x16xf32> { 895 %c0 = arith.constant 0 : index 896 // CHECK: vector.gather %{{.*}}[%{{.*}}] [%{{.*}}], %{{.*}}, %{{.*}} : tensor<?xf32>, vector<2x16xi32>, vector<2x16xi1>, vector<2x16xf32> into vector<2x16xf32> 897 %0 = vector.gather %base[%c0][%v], %mask, %pass_thru : tensor<?xf32>, vector<2x16xi32>, vector<2x16xi1>, vector<2x16xf32> into vector<2x16xf32> 898 return %0 : vector<2x16xf32> 899} 900 901// CHECK-LABEL: @expand_and_compress 902func.func @expand_and_compress(%base: memref<?xf32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) { 903 %c0 = arith.constant 0 : index 904 // CHECK: %[[X:.*]] = vector.expandload %{{.*}}[%{{.*}}], %{{.*}}, %{{.*}} : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 905 %0 = vector.expandload %base[%c0], %mask, %pass_thru : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 906 // CHECK: vector.compressstore %{{.*}}[%{{.*}}], %{{.*}}, %[[X]] : memref<?xf32>, vector<16xi1>, vector<16xf32> 907 vector.compressstore %base[%c0], %mask, %0 : memref<?xf32>, vector<16xi1>, vector<16xf32> 908 return 909} 910 911// CHECK-LABEL: @expand_and_compress2d 912func.func @expand_and_compress2d(%base: memref<?x?xf32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) { 913 %c0 = arith.constant 0 : index 914 // CHECK: %[[X:.*]] = vector.expandload %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}}, %{{.*}} : memref<?x?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 915 %0 = vector.expandload %base[%c0, %c0], %mask, %pass_thru : memref<?x?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 916 // CHECK: vector.compressstore %{{.*}}[%{{.*}}, %{{.*}}], %{{.*}}, %[[X]] : memref<?x?xf32>, vector<16xi1>, vector<16xf32> 917 vector.compressstore %base[%c0, %c0], %mask, %0 : memref<?x?xf32>, vector<16xi1>, vector<16xf32> 918 return 919} 920 921// CHECK-LABEL: @multi_reduction 922func.func @multi_reduction(%0: vector<4x8x16x32xf32>, %acc0: vector<4x16xf32>, 923 %acc1: f32) -> f32 { 924 // CHECK: vector.multi_reduction <add>, %{{.*}}, %{{.*}} [1, 3] : vector<4x8x16x32xf32> to vector<4x16xf32> 925 %1 = vector.multi_reduction <add>, %0, %acc0 [1, 3] : 926 vector<4x8x16x32xf32> to vector<4x16xf32> 927 // CHECK: vector.multi_reduction <add>, %{{.*}}, %{{.*}} [0, 1] : vector<4x16xf32> to f32 928 %2 = vector.multi_reduction <add>, %1, %acc1 [0, 1] : 929 vector<4x16xf32> to f32 930 return %2 : f32 931} 932 933// CHECK-LABEL: @get_vector_scale 934func.func @get_vector_scale() -> index { 935 // CHECK: vector.vscale 936 %0 = vector.vscale 937 return %0 : index 938} 939 940// CHECK-LABEL: @vector_scan 941func.func @vector_scan(%0: vector<4x8x16x32xf32>) -> vector<4x8x16x32xf32> { 942 %1 = arith.constant dense<0.0> : vector<4x16x32xf32> 943 %2:2 = vector.scan <add>, %0, %1 {reduction_dim = 1 : i64, inclusive = true} : 944 vector<4x8x16x32xf32>, vector<4x16x32xf32> 945 return %2#0 : vector<4x8x16x32xf32> 946} 947 948// CHECK-LABEL: func @test_splat_op 949// CHECK-SAME: [[S:%arg[0-9]+]]: f32 950func.func @test_splat_op(%s : f32) { 951 // CHECK: vector.splat [[S]] : vector<8xf32> 952 %v = vector.splat %s : vector<8xf32> 953 954 // CHECK: vector.splat [[S]] : vector<4xf32> 955 %u = "vector.splat"(%s) : (f32) -> vector<4xf32> 956 return 957} 958 959// CHECK-LABEL: func @vector_splat_0d( 960func.func @vector_splat_0d(%a: f32) -> vector<f32> { 961 // CHECK: vector.splat %{{.*}} : vector<f32> 962 %0 = vector.splat %a : vector<f32> 963 return %0 : vector<f32> 964} 965 966 967// CHECK-LABEL: func @vector_mask 968func.func @vector_mask(%a: vector<8xi32>, %m0: vector<8xi1>) -> i32 { 969// CHECK-NEXT: %{{.*}} = vector.mask %{{.*}} { vector.reduction <add>, %{{.*}} : vector<8xi32> into i32 } : vector<8xi1> -> i32 970 %0 = vector.mask %m0 { vector.reduction <add>, %a : vector<8xi32> into i32 } : vector<8xi1> -> i32 971 return %0 : i32 972} 973 974// CHECK-LABEL: func @vector_mask_passthru 975func.func @vector_mask_passthru(%t0: tensor<?xf32>, %idx: index, %m0: vector<16xi1>, %pt0: vector<16xf32>) -> vector<16xf32> { 976 %ft0 = arith.constant 0.0 : f32 977// CHECK: %{{.*}} = vector.mask %{{.*}}, %{{.*}} { vector.transfer_read %{{.*}}[%{{.*}}], %{{.*}} : tensor<?xf32>, vector<16xf32> } : vector<16xi1> -> vector<16xf32> 978 %0 = vector.mask %m0, %pt0 { vector.transfer_read %t0[%idx], %ft0 : tensor<?xf32>, vector<16xf32> } : vector<16xi1> -> vector<16xf32> 979 return %0 : vector<16xf32> 980} 981 982// CHECK-LABEL: func @vector_mask_no_return 983func.func @vector_mask_no_return(%val: vector<16xf32>, %t0: memref<?xf32>, %idx: index, %m0: vector<16xi1>) { 984// CHECK-NEXT: vector.mask %{{.*}} { vector.transfer_write %{{.*}}, %{{.*}}[%{{.*}}] : vector<16xf32>, memref<?xf32> } : vector<16xi1> 985 vector.mask %m0 { vector.transfer_write %val, %t0[%idx] : vector<16xf32>, memref<?xf32> } : vector<16xi1> 986 return 987} 988 989// CHECK-LABEL: func @vector_mask_tensor_return 990func.func @vector_mask_tensor_return(%val: vector<16xf32>, %t0: tensor<?xf32>, %idx: index, %m0: vector<16xi1>) { 991// CHECK-NEXT: vector.mask %{{.*}} { vector.transfer_write %{{.*}}, %{{.*}}[%{{.*}}] : vector<16xf32>, tensor<?xf32> } : vector<16xi1> -> tensor<?xf32> 992 vector.mask %m0 { vector.transfer_write %val, %t0[%idx] : vector<16xf32>, tensor<?xf32> } : vector<16xi1> -> tensor<?xf32> 993 return 994} 995 996// CHECK-LABEL: func @vector_mask_empty 997func.func @vector_mask_empty(%m0: vector<16xi1>) { 998// CHECK: vector.mask %{{.*}} { vector.yield } : vector<16xi1> 999 vector.mask %m0 { } : vector<16xi1> 1000 return 1001} 1002 1003// CHECK-LABEL: func @vector_mask_empty_with_yield 1004func.func @vector_mask_empty_with_yield(%m0: vector<16xi1>) { 1005// CHECK: vector.mask %{{.*}} { vector.yield } : vector<16xi1> 1006 vector.mask %m0 { vector.yield } : vector<16xi1> 1007 return 1008} 1009 1010// CHECK-LABEL: func @vector_mask_empty_return 1011func.func @vector_mask_empty_return(%m0: vector<16xi1>, %arg0: vector<16xf32>) -> vector<16xf32> { 1012// CHECK: vector.mask %{{.*}} { vector.yield {{.*}} : vector<16xf32> } : vector<16xi1> -> vector<16xf32> 1013 %0 = vector.mask %m0 { vector.yield %arg0 : vector<16xf32> } : vector<16xi1> -> vector<16xf32> 1014 return %0 : vector<16xf32> 1015} 1016 1017// CHECK-LABEL: func @vector_mask_scalar_broadcast_transfer 1018func.func @vector_mask_scalar_broadcast_transfer(%arg0: tensor<2x4xi32>, 1019 %idx0: index, %idx1: index, 1020 %m0: vector<1xi1>) -> vector<1x1x4xi32> { 1021 %cst = arith.constant 0 : i32 1022 // CHECK: vector.mask %{{.*}} { vector.transfer_read {{.*}} } : vector<1xi1> -> vector<1x1x4xi32> 1023 %res = vector.mask %m0 { 1024 %0 = vector.transfer_read %arg0[%idx0, %idx1], %cst {permutation_map = affine_map<(d0, d1) -> (0, 0, 0)>} 1025 : tensor<2x4xi32>, vector<1x1x4xi32> 1026 vector.yield %0 : vector<1x1x4xi32> 1027 } : vector<1xi1> -> vector<1x1x4xi32> 1028 return %res : vector<1x1x4xi32> 1029} 1030 1031// CHECK-LABEL: func @vector_scalable_insert( 1032// CHECK-SAME: %[[SUB0:.*]]: vector<4xi32>, %[[SUB1:.*]]: vector<8xi32>, 1033// CHECK-SAME: %[[SUB2:.*]]: vector<[4]xi32>, %[[SV:.*]]: vector<[8]xi32> 1034func.func @vector_scalable_insert(%sub0: vector<4xi32>, %sub1: vector<8xi32>, 1035 %sub2: vector<[4]xi32>, %sv: vector<[8]xi32>) { 1036 // CHECK-NEXT: vector.scalable.insert %[[SUB0]], %[[SV]][12] : vector<4xi32> into vector<[8]xi32> 1037 %0 = vector.scalable.insert %sub0, %sv[12] : vector<4xi32> into vector<[8]xi32> 1038 // CHECK-NEXT: vector.scalable.insert %[[SUB1]], %[[SV]][0] : vector<8xi32> into vector<[8]xi32> 1039 %1 = vector.scalable.insert %sub1, %sv[0] : vector<8xi32> into vector<[8]xi32> 1040 // CHECK-NEXT: vector.scalable.insert %[[SUB2]], %[[SV]][0] : vector<[4]xi32> into vector<[8]xi32> 1041 %2 = vector.scalable.insert %sub2, %sv[0] : vector<[4]xi32> into vector<[8]xi32> 1042 return 1043 } 1044 1045// CHECK-LABEL: func @vector_scalable_extract( 1046// CHECK-SAME: %[[SV:.*]]: vector<[8]xi32> 1047func.func @vector_scalable_extract(%sv: vector<[8]xi32>) { 1048 // CHECK-NEXT: vector.scalable.extract %[[SV]][0] : vector<16xi32> from vector<[8]xi32> 1049 %0 = vector.scalable.extract %sv[0] : vector<16xi32> from vector<[8]xi32> 1050 // CHECK-NEXT: vector.scalable.extract %[[SV]][0] : vector<[4]xi32> from vector<[8]xi32> 1051 %1 = vector.scalable.extract %sv[0] : vector<[4]xi32> from vector<[8]xi32> 1052 // CHECK-NEXT: vector.scalable.extract %[[SV]][4] : vector<4xi32> from vector<[8]xi32> 1053 %2 = vector.scalable.extract %sv[4] : vector<4xi32> from vector<[8]xi32> 1054 return 1055 } 1056 1057#matmat_accesses = [ 1058 affine_map<(i, j, k) -> (i, k)>, 1059 affine_map<(i, j, k) -> (k, j)>, 1060 affine_map<(i, j, k) -> (i, j)> 1061] 1062#matmat_trait = { 1063 indexing_maps = #matmat_accesses, 1064 iterator_types = ["parallel", "parallel", "reduction"] 1065} 1066// CHECK-LABEL: func.func @contraction_masked_scalable( 1067// CHECK-SAME: %[[A:.*]]: vector<3x4xf32>, 1068// CHECK-SAME: %[[B:.*]]: vector<4x[8]xf32>, 1069// CHECK-SAME: %[[C:.*]]: vector<3x[8]xf32>, 1070// CHECK-SAME: %[[M:.*]]: vector<3x[8]x4xi1>) -> vector<3x[8]xf32> { 1071func.func @contraction_masked_scalable(%A: vector<3x4xf32>, 1072 %B: vector<4x[8]xf32>, 1073 %C: vector<3x[8]xf32>, 1074 %M : vector<3x[8]x4xi1>) -> vector<3x[8]xf32> { 1075 // CHECK: vector.mask %[[M]] { vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %[[A]], %[[B]], %[[C]] : vector<3x4xf32>, vector<4x[8]xf32> into vector<3x[8]xf32> } : vector<3x[8]x4xi1> -> vector<3x[8]xf32> 1076 %0 = vector.mask %M { vector.contract #matmat_trait %A, %B, %C : vector<3x4xf32>, vector<4x[8]xf32> into vector<3x[8]xf32> } 1077 : vector<3x[8]x4xi1> -> vector<3x[8]xf32> 1078 return %0 : vector<3x[8]xf32> 1079} 1080 1081// CHECK-LABEL: func.func @fastmath( 1082func.func @fastmath(%x: vector<42xf32>) -> f32 { 1083 // CHECK: vector.reduction <minnumf>, %{{.*}} fastmath<reassoc,nnan,ninf> 1084 %min = vector.reduction <minnumf>, %x fastmath<reassoc,nnan,ninf> : vector<42xf32> into f32 1085 return %min: f32 1086} 1087 1088// CHECK-LABEL: @interleave_0d 1089func.func @interleave_0d(%a: vector<f32>, %b: vector<f32>) -> vector<2xf32> { 1090 // CHECK: vector.interleave %{{.*}}, %{{.*}} : vector<f32> -> vector<2xf32> 1091 %0 = vector.interleave %a, %b : vector<f32> -> vector<2xf32> 1092 return %0 : vector<2xf32> 1093} 1094 1095// CHECK-LABEL: @interleave_1d 1096func.func @interleave_1d(%a: vector<4xf32>, %b: vector<4xf32>) -> vector<8xf32> { 1097 // CHECK: vector.interleave %{{.*}}, %{{.*}} : vector<4xf32> 1098 %0 = vector.interleave %a, %b : vector<4xf32> -> vector<8xf32> 1099 return %0 : vector<8xf32> 1100} 1101 1102// CHECK-LABEL: @interleave_1d_scalable 1103func.func @interleave_1d_scalable(%a: vector<[8]xi16>, %b: vector<[8]xi16>) -> vector<[16]xi16> { 1104 // CHECK: vector.interleave %{{.*}}, %{{.*}} : vector<[8]xi16> 1105 %0 = vector.interleave %a, %b : vector<[8]xi16> -> vector<[16]xi16> 1106 return %0 : vector<[16]xi16> 1107} 1108 1109// CHECK-LABEL: @interleave_2d 1110func.func @interleave_2d(%a: vector<2x8xf32>, %b: vector<2x8xf32>) -> vector<2x16xf32> { 1111 // CHECK: vector.interleave %{{.*}}, %{{.*}} : vector<2x8xf32> 1112 %0 = vector.interleave %a, %b : vector<2x8xf32> -> vector<2x16xf32> 1113 return %0 : vector<2x16xf32> 1114} 1115 1116// CHECK-LABEL: @interleave_2d_scalable 1117func.func @interleave_2d_scalable(%a: vector<2x[2]xf64>, %b: vector<2x[2]xf64>) -> vector<2x[4]xf64> { 1118 // CHECK: vector.interleave %{{.*}}, %{{.*}} : vector<2x[2]xf64> 1119 %0 = vector.interleave %a, %b : vector<2x[2]xf64> -> vector<2x[4]xf64> 1120 return %0 : vector<2x[4]xf64> 1121} 1122 1123// CHECK-LABEL: @deinterleave_1d 1124func.func @deinterleave_1d(%arg: vector<4xf32>) -> (vector<2xf32>, vector<2xf32>) { 1125 // CHECK: vector.deinterleave %{{.*}} : vector<4xf32> -> vector<2xf32> 1126 %0, %1 = vector.deinterleave %arg : vector<4xf32> -> vector<2xf32> 1127 return %0, %1 : vector<2xf32>, vector<2xf32> 1128} 1129 1130// CHECK-LABEL: @deinterleave_1d_scalable 1131func.func @deinterleave_1d_scalable(%arg: vector<[4]xf32>) -> (vector<[2]xf32>, vector<[2]xf32>) { 1132 // CHECK: vector.deinterleave %{{.*}} : vector<[4]xf32> -> vector<[2]xf32> 1133 %0, %1 = vector.deinterleave %arg : vector<[4]xf32> -> vector<[2]xf32> 1134 return %0, %1 : vector<[2]xf32>, vector<[2]xf32> 1135} 1136 1137// CHECK-LABEL: @deinterleave_2d 1138func.func @deinterleave_2d(%arg: vector<3x4xf32>) -> (vector<3x2xf32>, vector<3x2xf32>) { 1139 // CHECK: vector.deinterleave %{{.*}} : vector<3x4xf32> -> vector<3x2xf32> 1140 %0, %1 = vector.deinterleave %arg : vector<3x4xf32> -> vector<3x2xf32> 1141 return %0, %1 : vector<3x2xf32>, vector<3x2xf32> 1142} 1143 1144// CHECK-LABEL: @deinterleave_2d_scalable 1145func.func @deinterleave_2d_scalable(%arg: vector<3x[4]xf32>) -> (vector<3x[2]xf32>, vector<3x[2]xf32>) { 1146 // CHECK: vector.deinterleave %{{.*}} : vector<3x[4]xf32> -> vector<3x[2]xf32> 1147 %0, %1 = vector.deinterleave %arg : vector<3x[4]xf32> -> vector<3x[2]xf32> 1148 return %0, %1 : vector<3x[2]xf32>, vector<3x[2]xf32> 1149} 1150 1151// CHECK-LABEL: @deinterleave_nd 1152func.func @deinterleave_nd(%arg: vector<2x3x4x6xf32>) -> (vector<2x3x4x3xf32>, vector<2x3x4x3xf32>) { 1153 // CHECK: vector.deinterleave %{{.*}} : vector<2x3x4x6xf32> -> vector<2x3x4x3xf32> 1154 %0, %1 = vector.deinterleave %arg : vector<2x3x4x6xf32> -> vector<2x3x4x3xf32> 1155 return %0, %1 : vector<2x3x4x3xf32>, vector<2x3x4x3xf32> 1156} 1157 1158// CHECK-LABEL: @deinterleave_nd_scalable 1159func.func @deinterleave_nd_scalable(%arg:vector<2x3x4x[6]xf32>) -> (vector<2x3x4x[3]xf32>, vector<2x3x4x[3]xf32>) { 1160 // CHECK: vector.deinterleave %{{.*}} : vector<2x3x4x[6]xf32> -> vector<2x3x4x[3]xf32> 1161 %0, %1 = vector.deinterleave %arg : vector<2x3x4x[6]xf32> -> vector<2x3x4x[3]xf32> 1162 return %0, %1 : vector<2x3x4x[3]xf32>, vector<2x3x4x[3]xf32> 1163} 1164 1165// CHECK-LABEL: func @from_elements( 1166// CHECK-SAME: %[[a:.*]]: f32, %[[b:.*]]: f32) 1167func.func @from_elements(%a: f32, %b: f32) -> (vector<f32>, vector<1xf32>, vector<1x2xf32>, vector<2x2xf32>) { 1168 // CHECK: vector.from_elements %[[a]] : vector<f32> 1169 %0 = vector.from_elements %a : vector<f32> 1170 // CHECK: vector.from_elements %[[a]] : vector<1xf32> 1171 %1 = vector.from_elements %a : vector<1xf32> 1172 // CHECK: vector.from_elements %[[a]], %[[b]] : vector<1x2xf32> 1173 %2 = vector.from_elements %a, %b : vector<1x2xf32> 1174 // CHECK: vector.from_elements %[[b]], %[[b]], %[[a]], %[[a]] : vector<2x2xf32> 1175 %3 = vector.from_elements %b, %b, %a, %a : vector<2x2xf32> 1176 return %0, %1, %2, %3 : vector<f32>, vector<1xf32>, vector<1x2xf32>, vector<2x2xf32> 1177} 1178 1179// CHECK-LABEL: @step 1180func.func @step() { 1181 // CHECK: vector.step : vector<2xindex> 1182 %0 = vector.step : vector<2xindex> 1183 // CHECK: vector.step : vector<[4]xindex> 1184 %1 = vector.step : vector<[4]xindex> 1185 return 1186} 1187