1// RUN: mlir-opt %s | mlir-opt | FileCheck %s 2 3// CHECK-LABEL: func @vector_transfer_ops( 4func @vector_transfer_ops(%arg0: memref<?x?xf32>, 5 %arg1 : memref<?x?xvector<4x3xf32>>, 6 %arg2 : memref<?x?xvector<4x3xi32>>) { 7 // CHECK: %[[C3:.*]] = constant 3 : index 8 %c3 = constant 3 : index 9 %cst = constant 3.0 : f32 10 %f0 = constant 0.0 : f32 11 %c0 = constant 0 : i32 12 %vf0 = splat %f0 : vector<4x3xf32> 13 %v0 = splat %c0 : vector<4x3xi32> 14 15 // 16 // CHECK: vector.transfer_read 17 %0 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d0)>} : memref<?x?xf32>, vector<128xf32> 18 // CHECK: vector.transfer_read 19 %1 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : memref<?x?xf32>, vector<3x7xf32> 20 // CHECK: vector.transfer_read 21 %2 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d0)>} : memref<?x?xf32>, vector<128xf32> 22 // CHECK: vector.transfer_read 23 %3 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d1)>} : memref<?x?xf32>, vector<128xf32> 24 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 25 %4 = vector.transfer_read %arg1[%c3, %c3], %vf0 {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 26 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} {masked = [true, false]} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 27 %5 = vector.transfer_read %arg1[%c3, %c3], %vf0 {masked = [true, false]} : memref<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 28 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : memref<?x?xvector<4x3xi32>>, vector<5x24xi8> 29 %6 = vector.transfer_read %arg2[%c3, %c3], %v0 : memref<?x?xvector<4x3xi32>>, vector<5x24xi8> 30 31 32 // CHECK: vector.transfer_write 33 vector.transfer_write %0, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0)>} : vector<128xf32>, memref<?x?xf32> 34 // CHECK: vector.transfer_write 35 vector.transfer_write %1, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : vector<3x7xf32>, memref<?x?xf32> 36 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 37 vector.transfer_write %4, %arg1[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 38 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 39 vector.transfer_write %5, %arg1[%c3, %c3] {masked = [true, true]} : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>> 40 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<5x24xi8>, memref<?x?xvector<4x3xi32>> 41 vector.transfer_write %6, %arg2[%c3, %c3] : vector<5x24xi8>, memref<?x?xvector<4x3xi32>> 42 43 return 44} 45 46 47// CHECK-LABEL: func @vector_transfer_ops_tensor( 48func @vector_transfer_ops_tensor(%arg0: tensor<?x?xf32>, 49 %arg1 : tensor<?x?xvector<4x3xf32>>, 50 %arg2 : tensor<?x?xvector<4x3xi32>>) -> 51 (tensor<?x?xf32>, tensor<?x?xf32>, tensor<?x?xvector<4x3xf32>>, 52 tensor<?x?xvector<4x3xf32>>, tensor<?x?xvector<4x3xi32>>){ 53 // CHECK: %[[C3:.*]] = constant 3 : index 54 %c3 = constant 3 : index 55 %cst = constant 3.0 : f32 56 %f0 = constant 0.0 : f32 57 %c0 = constant 0 : i32 58 %vf0 = splat %f0 : vector<4x3xf32> 59 %v0 = splat %c0 : vector<4x3xi32> 60 61 // 62 // CHECK: vector.transfer_read 63 %0 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d0)>} : tensor<?x?xf32>, vector<128xf32> 64 // CHECK: vector.transfer_read 65 %1 = vector.transfer_read %arg0[%c3, %c3], %f0 {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : tensor<?x?xf32>, vector<3x7xf32> 66 // CHECK: vector.transfer_read 67 %2 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d0)>} : tensor<?x?xf32>, vector<128xf32> 68 // CHECK: vector.transfer_read 69 %3 = vector.transfer_read %arg0[%c3, %c3], %cst {permutation_map = affine_map<(d0, d1)->(d1)>} : tensor<?x?xf32>, vector<128xf32> 70 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 71 %4 = vector.transfer_read %arg1[%c3, %c3], %vf0 {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 72 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} {masked = [true, false]} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 73 %5 = vector.transfer_read %arg1[%c3, %c3], %vf0 {masked = [true, false]} : tensor<?x?xvector<4x3xf32>>, vector<1x1x4x3xf32> 74 // CHECK: vector.transfer_read %{{.*}}[%[[C3]], %[[C3]]], %{{.*}} : tensor<?x?xvector<4x3xi32>>, vector<5x24xi8> 75 %6 = vector.transfer_read %arg2[%c3, %c3], %v0 : tensor<?x?xvector<4x3xi32>>, vector<5x24xi8> 76 77 78 // CHECK: vector.transfer_write 79 %7 = vector.transfer_write %0, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0)>} : vector<128xf32>, tensor<?x?xf32> 80 // CHECK: vector.transfer_write 81 %8 = vector.transfer_write %1, %arg0[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d1, d0)>} : vector<3x7xf32>, tensor<?x?xf32> 82 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 83 %9 = vector.transfer_write %4, %arg1[%c3, %c3] {permutation_map = affine_map<(d0, d1)->(d0, d1)>} : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 84 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 85 %10 = vector.transfer_write %5, %arg1[%c3, %c3] {masked = [true, true]} : vector<1x1x4x3xf32>, tensor<?x?xvector<4x3xf32>> 86 // CHECK: vector.transfer_write %{{.*}}, %{{.*}}[%[[C3]], %[[C3]]] : vector<5x24xi8>, tensor<?x?xvector<4x3xi32>> 87 %11 = vector.transfer_write %6, %arg2[%c3, %c3] : vector<5x24xi8>, tensor<?x?xvector<4x3xi32>> 88 89 return %7, %8, %9, %10, %11 : 90 tensor<?x?xf32>, tensor<?x?xf32>, tensor<?x?xvector<4x3xf32>>, 91 tensor<?x?xvector<4x3xf32>>, tensor<?x?xvector<4x3xi32>> 92} 93 94// CHECK-LABEL: @vector_broadcast 95func @vector_broadcast(%a: f32, %b: vector<16xf32>, %c: vector<1x16xf32>, %d: vector<8x1xf32>) -> vector<8x16xf32> { 96 // CHECK: vector.broadcast %{{.*}} : f32 to vector<16xf32> 97 %0 = vector.broadcast %a : f32 to vector<16xf32> 98 // CHECK-NEXT: vector.broadcast %{{.*}} : vector<16xf32> to vector<8x16xf32> 99 %1 = vector.broadcast %b : vector<16xf32> to vector<8x16xf32> 100 // CHECK-NEXT: vector.broadcast %{{.*}} : vector<1x16xf32> to vector<8x16xf32> 101 %2 = vector.broadcast %c : vector<1x16xf32> to vector<8x16xf32> 102 // CHECK-NEXT: vector.broadcast %{{.*}} : vector<8x1xf32> to vector<8x16xf32> 103 %3 = vector.broadcast %d : vector<8x1xf32> to vector<8x16xf32> 104 return %3 : vector<8x16xf32> 105} 106 107// CHECK-LABEL: @shuffle1D 108func @shuffle1D(%a: vector<2xf32>, %b: vector<4xf32>) -> vector<2xf32> { 109 // CHECK: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 2, 3] : vector<2xf32>, vector<2xf32> 110 %1 = vector.shuffle %a, %a[0, 1, 2, 3] : vector<2xf32>, vector<2xf32> 111 // CHECK-NEXT: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 2] : vector<4xf32>, vector<4xf32> 112 %2 = vector.shuffle %1, %b[0, 1, 2] : vector<4xf32>, vector<4xf32> 113 // CHECK-NEXT: vector.shuffle %{{.*}}, %{{.*}}[0, 6] : vector<3xf32>, vector<4xf32> 114 %3 = vector.shuffle %2, %b[0, 6] : vector<3xf32>, vector<4xf32> 115 return %3 : vector<2xf32> 116} 117 118// CHECK-LABEL: @shuffle2D 119func @shuffle2D(%a: vector<1x4xf32>, %b: vector<2x4xf32>) -> vector<3x4xf32> { 120 // CHECK: vector.shuffle %{{.*}}, %{{.*}}[0, 1, 2] : vector<1x4xf32>, vector<2x4xf32> 121 %1 = vector.shuffle %a, %b[0, 1, 2] : vector<1x4xf32>, vector<2x4xf32> 122 return %1 : vector<3x4xf32> 123} 124 125// CHECK-LABEL: @extract_element 126func @extract_element(%a: vector<16xf32>) -> f32 { 127 // CHECK: %[[C15:.*]] = constant 15 : i32 128 %c = constant 15 : i32 129 // CHECK-NEXT: vector.extractelement %{{.*}}[%[[C15]] : i32] : vector<16xf32> 130 %1 = vector.extractelement %a[%c : i32] : vector<16xf32> 131 return %1 : f32 132} 133 134// CHECK-LABEL: @extract 135func @extract(%arg0: vector<4x8x16xf32>) -> (vector<8x16xf32>, vector<16xf32>, f32) { 136 // CHECK: vector.extract {{.*}}[3] : vector<4x8x16xf32> 137 %1 = vector.extract %arg0[3] : vector<4x8x16xf32> 138 // CHECK-NEXT: vector.extract {{.*}}[3, 3] : vector<4x8x16xf32> 139 %2 = vector.extract %arg0[3, 3] : vector<4x8x16xf32> 140 // CHECK-NEXT: vector.extract {{.*}}[3, 3, 3] : vector<4x8x16xf32> 141 %3 = vector.extract %arg0[3, 3, 3] : vector<4x8x16xf32> 142 return %1, %2, %3 : vector<8x16xf32>, vector<16xf32>, f32 143} 144 145// CHECK-LABEL: @insert_element 146func @insert_element(%a: f32, %b: vector<16xf32>) -> vector<16xf32> { 147 // CHECK: %[[C15:.*]] = constant 15 : i32 148 %c = constant 15 : i32 149 // CHECK-NEXT: vector.insertelement %{{.*}}, %{{.*}}[%[[C15]] : i32] : vector<16xf32> 150 %1 = vector.insertelement %a, %b[%c : i32] : vector<16xf32> 151 return %1 : vector<16xf32> 152} 153 154// CHECK-LABEL: @insert 155func @insert(%a: f32, %b: vector<16xf32>, %c: vector<8x16xf32>, %res: vector<4x8x16xf32>) -> vector<4x8x16xf32> { 156 // CHECK: vector.insert %{{.*}}, %{{.*}}[3] : vector<8x16xf32> into vector<4x8x16xf32> 157 %1 = vector.insert %c, %res[3] : vector<8x16xf32> into vector<4x8x16xf32> 158 // CHECK: vector.insert %{{.*}}, %{{.*}}[3, 3] : vector<16xf32> into vector<4x8x16xf32> 159 %2 = vector.insert %b, %res[3, 3] : vector<16xf32> into vector<4x8x16xf32> 160 // CHECK: vector.insert %{{.*}}, %{{.*}}[3, 3, 3] : f32 into vector<4x8x16xf32> 161 %3 = vector.insert %a, %res[3, 3, 3] : f32 into vector<4x8x16xf32> 162 return %3 : vector<4x8x16xf32> 163} 164 165// CHECK-LABEL: @outerproduct 166func @outerproduct(%arg0: vector<4xf32>, %arg1: vector<8xf32>, %arg2: vector<4x8xf32>) -> vector<4x8xf32> { 167 // CHECK: vector.outerproduct {{.*}} : vector<4xf32>, vector<8xf32> 168 %0 = vector.outerproduct %arg0, %arg1 : vector<4xf32>, vector<8xf32> 169 // CHECK: vector.outerproduct {{.*}}, {{.*}}, {{.*}} : vector<4xf32>, vector<8xf32> 170 %1 = vector.outerproduct %arg0, %arg1, %arg2 : vector<4xf32>, vector<8xf32> 171 return %1 : vector<4x8xf32> 172} 173 174// CHECK-LABEL: @insert_strided_slice 175func @insert_strided_slice(%a: vector<4x4xf32>, %b: vector<4x8x16xf32>) { 176 // CHECK: vector.insert_strided_slice %{{.*}}, %{{.*}} {offsets = [2, 2, 2], strides = [1, 1]} : vector<4x4xf32> into vector<4x8x16xf32> 177 %1 = vector.insert_strided_slice %a, %b {offsets = [2, 2, 2], strides = [1, 1]} : vector<4x4xf32> into vector<4x8x16xf32> 178 return 179} 180 181// CHECK-LABEL: @extract_strided_slice 182func @extract_strided_slice(%arg0: vector<4x8x16xf32>) -> vector<2x2x16xf32> { 183 // CHECK: vector.extract_strided_slice %{{.*}} {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8x16xf32> 184 %1 = vector.extract_strided_slice %arg0 {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8x16xf32> to vector<2x2x16xf32> 185 return %1: vector<2x2x16xf32> 186} 187 188#contraction_to_scalar_accesses = [ 189 affine_map<(i) -> (i)>, 190 affine_map<(i) -> (i)>, 191 affine_map<(i) -> ()> 192] 193#contraction_to_scalar_trait = { 194 indexing_maps = #contraction_to_scalar_accesses, 195 iterator_types = ["reduction"] 196} 197// CHECK-LABEL: @contraction_to_scalar 198func @contraction_to_scalar(%arg0: vector<10xf32>, %arg1: vector<10xf32>) -> f32 { 199 // CHECK: %[[C0:.*]] = constant 0.000000e+00 : f32 200 %f0 = constant 0.0: f32 201 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["reduction"], kind = #vector.kind<add>} %{{.*}}, %{{.*}}, %[[C0]] : vector<10xf32>, vector<10xf32> into f32 202 %0 = vector.contract #contraction_to_scalar_trait %arg0, %arg1, %f0 203 : vector<10xf32>, vector<10xf32> into f32 204 // CHECK: return %[[X]] : f32 205 return %0 : f32 206} 207 208#contraction_to_scalar_max_accesses = [ 209 affine_map<(i) -> (i)>, 210 affine_map<(i) -> (i)>, 211 affine_map<(i) -> ()> 212] 213#contraction_to_scalar_max_trait = { 214 indexing_maps = #contraction_to_scalar_max_accesses, 215 iterator_types = ["reduction"], 216 kind = #vector.kind<max> 217} 218// CHECK-LABEL: @contraction_to_scalar_with_max 219func @contraction_to_scalar_with_max(%arg0: vector<10xf32>, %arg1: vector<10xf32>) -> f32 { 220 // CHECK: %[[C0:.*]] = constant 0.000000e+00 : f32 221 %f0 = constant 0.0: f32 222 // CHECK: %[[X:.*]] = vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["reduction"], kind = #vector.kind<max>} %{{.*}}, %{{.*}}, %[[C0]] : vector<10xf32>, vector<10xf32> into f32 223 %0 = vector.contract #contraction_to_scalar_max_trait %arg0, %arg1, %f0 224 : vector<10xf32>, vector<10xf32> into f32 225 // CHECK: return %[[X]] : f32 226 return %0 : f32 227} 228 229#contraction_accesses0 = [ 230 affine_map<(b0, f0, f1, c0, c1) -> (c0, b0, c1, f0)>, 231 affine_map<(b0, f0, f1, c0, c1) -> (b0, c1, c0, f1)>, 232 affine_map<(b0, f0, f1, c0, c1) -> (b0, f0, f1)> 233] 234#contraction_trait0 = { 235 indexing_maps = #contraction_accesses0, 236 iterator_types = ["parallel", "parallel", "parallel", "reduction", "reduction"] 237} 238#contraction_accesses1 = [ // 7, 8, 16, 15 239 affine_map<(f0, f1, f2, f3, c0, c1) -> (c0, f0, c1, f2)>, 240 // 8, 16, 7, 5 241 affine_map<(f0, f1, f2, f3, c0, c1) -> (f1, c1, c0, f3)>, 242 // 8, 8, 15, 5 243 affine_map<(f0, f1, f2, f3, c0, c1) -> (f0, f1, f2, f3)> 244] 245#iterator_types1 = ["parallel", "parallel", "parallel", "parallel", "reduction", 246 "reduction"] 247#contraction_trait1 = { 248 indexing_maps = #contraction_accesses1, 249 iterator_types = #iterator_types1 250} 251#contraction_trait2 = { 252 indexing_maps = #contraction_accesses1, 253 iterator_types = #iterator_types1, 254 kind = #vector.kind<max> 255} 256// CHECK-LABEL: @contraction 257func @contraction(%arg0 : vector<7x8x16x15xf32>, %arg1 : vector<8x16x7x5xf32>, 258 %arg2 : vector<8x15x5xf32>, %arg3 : vector<8x8x15x5xf32>, 259 %arg4 : vector<7x8x16x15xf16>, %arg5 : vector<8x16x7x5xf16>) { 260 // Test contraction with batch and contracting dims. 261 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x15x5xf32> 262 %0 = vector.contract #contraction_trait0 %arg0, %arg1, %arg2 263 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x15x5xf32> 264 // Test contraction with only contracting dims. In this case the lhs/rhs 265 // dimension of size 8 will be considered a parallel dim for lhs/rhs and will 266 // appear twice in the output. 267 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 268 %1 = vector.contract #contraction_trait1 %arg0, %arg1, %arg3 269 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 270 // Test contraction with optional vector mask arguments. 271 %lhs_mask = vector.constant_mask [7, 8, 16, 15] : vector<7x8x16x15xi1> 272 %rhs_mask = vector.constant_mask [8, 16, 7, 5] : vector<8x16x7x5xi1> 273 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 274 %2 = vector.contract #contraction_trait1 %arg0, %arg1, %arg3, %lhs_mask, 275 %rhs_mask 276 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 277 // Test contraction with mixed type. 278 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<add>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf16>, vector<8x16x7x5xf16> into vector<8x8x15x5xf32> 279 %3 = vector.contract #contraction_trait1 %arg4, %arg5, %arg3 280 : vector<7x8x16x15xf16>, vector<8x16x7x5xf16> into vector<8x8x15x5xf32> 281 // Test contraction with "max" instead of "add". 282 // CHECK: vector.contract {indexing_maps = [#{{.*}}, #{{.*}}, #{{.*}}], iterator_types = ["parallel", "parallel", "parallel", "parallel", "reduction", "reduction"], kind = #vector.kind<max>} {{.*}}, {{.*}}, {{.*}} : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 283 %4 = vector.contract #contraction_trait2 %arg0, %arg1, %arg3 284 : vector<7x8x16x15xf32>, vector<8x16x7x5xf32> into vector<8x8x15x5xf32> 285 return 286} 287 288// CHECK-LABEL: @create_vector_mask 289func @create_vector_mask() { 290 // CHECK: %[[C2:.*]] = constant 2 : index 291 %c2 = constant 2 : index 292 // CHECK-NEXT: %[[C3:.*]] = constant 3 : index 293 %c3 = constant 3 : index 294 // CHECK-NEXT: vector.create_mask %[[C3]], %[[C2]] : vector<4x3xi1> 295 %0 = vector.create_mask %c3, %c2 : vector<4x3xi1> 296 297 return 298} 299 300// CHECK-LABEL: @constant_vector_mask 301func @constant_vector_mask() { 302 // CHECK: vector.constant_mask [3, 2] : vector<4x3xi1> 303 %0 = vector.constant_mask [3, 2] : vector<4x3xi1> 304 return 305} 306 307// CHECK-LABEL: @extract_slices 308func @extract_slices(%arg0 : vector<4x2xf32>) 309 -> (tuple<vector<2x2xf32>, vector<2x2xf32>>) { 310 // CHECK: vector.extract_slices %{{.*}}, [2, 2], [1, 1] : vector<4x2xf32> into tuple<vector<2x2xf32>, vector<2x2xf32>> 311 %0 = vector.extract_slices %arg0, [2, 2], [1, 1] 312 : vector<4x2xf32> into tuple<vector<2x2xf32>, vector<2x2xf32>> 313 %1 = vector.tuple_get %0, 0 : tuple<vector<2x2xf32>, vector<2x2xf32>> 314 %2 = vector.tuple_get %0, 1 : tuple<vector<2x2xf32>, vector<2x2xf32>> 315 %3 = vector.tuple %1, %2 : vector<2x2xf32>, vector<2x2xf32> 316 return %3 : tuple<vector<2x2xf32>, vector<2x2xf32>> 317} 318 319// CHECK-LABEL: @insert_slices 320func @insert_slices(%arg0 : tuple<vector<2x2xf32>, vector<2x2xf32>>) 321 -> (vector<4x2xf32>) { 322 // CHECK: vector.insert_slices %{{.*}}, [2, 2], [1, 1] : tuple<vector<2x2xf32>, vector<2x2xf32>> into vector<4x2xf32> 323 %0 = vector.insert_slices %arg0, [2, 2], [1, 1] 324 : tuple<vector<2x2xf32>, vector<2x2xf32>> into vector<4x2xf32> 325 return %0 : vector<4x2xf32> 326} 327 328// CHECK-LABEL: @vector_print 329func @vector_print(%arg0: vector<8x4xf32>) { 330 // CHECK: vector.print %{{.*}} : vector<8x4xf32> 331 vector.print %arg0 : vector<8x4xf32> 332 return 333} 334 335// CHECK-LABEL: @reshape 336func @reshape(%arg0 : vector<3x2x4xf32>) -> (vector<2x3x4xf32>) { 337 // CHECK: %[[C2:.*]] = constant 2 : index 338 %c2 = constant 2 : index 339 // CHECK: %[[C3:.*]] = constant 3 : index 340 %c3 = constant 3 : index 341 // CHECK: %[[C6:.*]] = constant 6 : index 342 %c6 = constant 6 : index 343 // CHECK: %[[C9:.*]] = constant 9 : index 344 %c9 = constant 9 : index 345 // CHECK: vector.reshape %{{.*}}, [%[[C3]], %[[C6]]], [%[[C2]], %[[C9]]], [4] : vector<3x2x4xf32> to vector<2x3x4xf32> 346 %1 = vector.reshape %arg0, [%c3, %c6], [%c2, %c9], [4] 347 : vector<3x2x4xf32> to vector<2x3x4xf32> 348 349 return %1 : vector<2x3x4xf32> 350} 351 352// CHECK-LABEL: @shape_cast 353func @shape_cast(%arg0 : vector<5x1x3x2xf32>, 354 %arg1 : tuple<vector<5x4x2xf32>, vector<3x4x2xf32>>, 355 %arg2 : vector<8x1xf32>, 356 %arg3 : vector<16x1x1xf32>) 357 -> (vector<15x2xf32>, tuple<vector<20x2xf32>, vector<12x2xf32>>, vector<8xf32>, vector<16xf32>, vector<16x1xf32>) { 358 359 // CHECK: vector.shape_cast %{{.*}} : vector<5x1x3x2xf32> to vector<15x2xf32> 360 %0 = vector.shape_cast %arg0 : vector<5x1x3x2xf32> to vector<15x2xf32> 361 362 // CHECK-NEXT: vector.shape_cast %{{.*}} : tuple<vector<5x4x2xf32>, vector<3x4x2xf32>> to tuple<vector<20x2xf32>, vector<12x2xf32>> 363 %1 = vector.shape_cast %arg1 : tuple<vector<5x4x2xf32>, vector<3x4x2xf32>> to 364 tuple<vector<20x2xf32>, vector<12x2xf32>> 365 366 // CHECK-NEXT: vector.shape_cast %{{.*}} : vector<8x1xf32> to vector<8xf32> 367 %2 = vector.shape_cast %arg2 : vector<8x1xf32> to vector<8xf32> 368 369 // CHECK-NEXT: vector.shape_cast %{{.*}} : vector<16x1x1xf32> to vector<16xf32> 370 %3 = vector.shape_cast %arg3 : vector<16x1x1xf32> to vector<16xf32> 371 372 // CHECK-NEXT: vector.shape_cast %{{.*}} : vector<16x1x1xf32> to vector<16x1xf32> 373 %4 = vector.shape_cast %arg3 : vector<16x1x1xf32> to vector<16x1xf32> 374 375 return %0, %1, %2, %3, %4 : vector<15x2xf32>, tuple<vector<20x2xf32>, vector<12x2xf32>>, vector<8xf32>, vector<16xf32>, vector<16x1xf32> 376} 377 378// CHECK-LABEL: @bitcast 379func @bitcast(%arg0 : vector<5x1x3x2xf32>, 380 %arg1 : vector<8x1xi32>, 381 %arg2 : vector<16x1x8xi8>) 382 -> (vector<5x1x3x4xf16>, vector<5x1x3x8xi8>, vector<8x4xi8>, vector<8x1xf32>, vector<16x1x2xi32>, vector<16x1x4xi16>) { 383 384 // CHECK: vector.bitcast %{{.*}} : vector<5x1x3x2xf32> to vector<5x1x3x4xf16> 385 %0 = vector.bitcast %arg0 : vector<5x1x3x2xf32> to vector<5x1x3x4xf16> 386 387 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<5x1x3x2xf32> to vector<5x1x3x8xi8> 388 %1 = vector.bitcast %arg0 : vector<5x1x3x2xf32> to vector<5x1x3x8xi8> 389 390 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<8x1xi32> to vector<8x4xi8> 391 %2 = vector.bitcast %arg1 : vector<8x1xi32> to vector<8x4xi8> 392 393 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<8x1xi32> to vector<8x1xf32> 394 %3 = vector.bitcast %arg1 : vector<8x1xi32> to vector<8x1xf32> 395 396 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<16x1x8xi8> to vector<16x1x2xi32> 397 %4 = vector.bitcast %arg2 : vector<16x1x8xi8> to vector<16x1x2xi32> 398 399 // CHECK-NEXT: vector.bitcast %{{.*}} : vector<16x1x8xi8> to vector<16x1x4xi16> 400 %5 = vector.bitcast %arg2 : vector<16x1x8xi8> to vector<16x1x4xi16> 401 402 return %0, %1, %2, %3, %4, %5 : vector<5x1x3x4xf16>, vector<5x1x3x8xi8>, vector<8x4xi8>, vector<8x1xf32>, vector<16x1x2xi32>, vector<16x1x4xi16> 403} 404 405// CHECK-LABEL: @vector_fma 406func @vector_fma(%a: vector<8xf32>, %b: vector<8x4xf32>) { 407 // CHECK: vector.fma %{{.*}} : vector<8xf32> 408 vector.fma %a, %a, %a : vector<8xf32> 409 // CHECK: vector.fma %{{.*}} : vector<8x4xf32> 410 vector.fma %b, %b, %b : vector<8x4xf32> 411 return 412} 413 414// CHECK-LABEL: @reduce_fp 415func @reduce_fp(%arg0: vector<16xf32>, %arg1: f32) -> f32 { 416 // CHECK: vector.reduction "add", %{{.*}} : vector<16xf32> into f32 417 vector.reduction "add", %arg0 : vector<16xf32> into f32 418 // CHECK: vector.reduction "add", %{{.*}}, %{{.*}} : vector<16xf32> into f32 419 vector.reduction "add", %arg0, %arg1 : vector<16xf32> into f32 420 // CHECK: vector.reduction "mul", %{{.*}} : vector<16xf32> into f32 421 vector.reduction "mul", %arg0 : vector<16xf32> into f32 422 // CHECK: vector.reduction "mul", %{{.*}}, %{{.*}} : vector<16xf32> into f32 423 vector.reduction "mul", %arg0, %arg1 : vector<16xf32> into f32 424 // CHECK: vector.reduction "min", %{{.*}} : vector<16xf32> into f32 425 vector.reduction "min", %arg0 : vector<16xf32> into f32 426 // CHECK: %[[X:.*]] = vector.reduction "max", %{{.*}} : vector<16xf32> into f32 427 %0 = vector.reduction "max", %arg0 : vector<16xf32> into f32 428 // CHECK: return %[[X]] : f32 429 return %0 : f32 430} 431 432// CHECK-LABEL: @reduce_int 433func @reduce_int(%arg0: vector<16xi32>) -> i32 { 434 // CHECK: vector.reduction "add", %{{.*}} : vector<16xi32> into i32 435 vector.reduction "add", %arg0 : vector<16xi32> into i32 436 // CHECK: vector.reduction "mul", %{{.*}} : vector<16xi32> into i32 437 vector.reduction "mul", %arg0 : vector<16xi32> into i32 438 // CHECK: vector.reduction "min", %{{.*}} : vector<16xi32> into i32 439 vector.reduction "min", %arg0 : vector<16xi32> into i32 440 // CHECK: vector.reduction "max", %{{.*}} : vector<16xi32> into i32 441 vector.reduction "max", %arg0 : vector<16xi32> into i32 442 // CHECK: vector.reduction "and", %{{.*}} : vector<16xi32> into i32 443 vector.reduction "and", %arg0 : vector<16xi32> into i32 444 // CHECK: vector.reduction "or", %{{.*}} : vector<16xi32> into i32 445 vector.reduction "or", %arg0 : vector<16xi32> into i32 446 // CHECK: %[[X:.*]] = vector.reduction "xor", %{{.*}} : vector<16xi32> into i32 447 %0 = vector.reduction "xor", %arg0 : vector<16xi32> into i32 448 // CHECK: return %[[X]] : i32 449 return %0 : i32 450} 451 452// CHECK-LABEL: @transpose_fp 453func @transpose_fp(%arg0: vector<3x7xf32>) -> vector<7x3xf32> { 454 // CHECK: %[[X:.*]] = vector.transpose %{{.*}}, [1, 0] : vector<3x7xf32> to vector<7x3xf32> 455 %0 = vector.transpose %arg0, [1, 0] : vector<3x7xf32> to vector<7x3xf32> 456 // CHECK: return %[[X]] : vector<7x3xf32> 457 return %0 : vector<7x3xf32> 458} 459 460// CHECK-LABEL: @transpose_int 461func @transpose_int(%arg0: vector<11x7x3x2xi32>) -> vector<2x11x7x3xi32> { 462 // CHECK: %[[X:.*]] = vector.transpose %{{.*}}, [3, 0, 1, 2] : vector<11x7x3x2xi32> to vector<2x11x7x3xi32> 463 %0 = vector.transpose %arg0, [3, 0, 1, 2] : vector<11x7x3x2xi32> to vector<2x11x7x3xi32> 464 // CHECK: return %[[X]] : vector<2x11x7x3xi32> 465 return %0 : vector<2x11x7x3xi32> 466} 467 468// CHECK-LABEL: @flat_transpose_fp 469func @flat_transpose_fp(%arg0: vector<16xf32>) -> vector<16xf32> { 470 // CHECK: %[[X:.*]] = vector.flat_transpose %{{.*}} {columns = 4 : i32, rows = 4 : i32} : vector<16xf32> -> vector<16xf32> 471 %0 = vector.flat_transpose %arg0 { rows = 4: i32, columns = 4: i32 } : vector<16xf32> -> vector<16xf32> 472 // CHECK: return %[[X]] : vector<16xf32> 473 return %0 : vector<16xf32> 474} 475 476// CHECK-LABEL: @flat_transpose_int 477func @flat_transpose_int(%arg0: vector<16xi32>) -> vector<16xi32> { 478 // CHECK: %[[X:.*]] = vector.flat_transpose %{{.*}} {columns = 8 : i32, rows = 2 : i32} : vector<16xi32> -> vector<16xi32> 479 %0 = vector.flat_transpose %arg0 { rows = 2: i32, columns = 8: i32 } : vector<16xi32> -> vector<16xi32> 480 // CHECK: return %[[X]] : vector<16xi32> 481 return %0 : vector<16xi32> 482} 483 484// CHECK-LABEL: @vector_load_and_store_1d_scalar_memref 485func @vector_load_and_store_1d_scalar_memref(%memref : memref<200x100xf32>, 486 %i : index, %j : index) { 487 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<8xf32> 488 %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<8xf32> 489 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<8xf32> 490 vector.store %0, %memref[%i, %j] : memref<200x100xf32>, vector<8xf32> 491 return 492} 493 494// CHECK-LABEL: @vector_load_and_store_1d_vector_memref 495func @vector_load_and_store_1d_vector_memref(%memref : memref<200x100xvector<8xf32>>, 496 %i : index, %j : index) { 497 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xvector<8xf32>>, vector<8xf32> 498 %0 = vector.load %memref[%i, %j] : memref<200x100xvector<8xf32>>, vector<8xf32> 499 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xvector<8xf32>>, vector<8xf32> 500 vector.store %0, %memref[%i, %j] : memref<200x100xvector<8xf32>>, vector<8xf32> 501 return 502} 503 504// CHECK-LABEL: @vector_load_and_store_out_of_bounds 505func @vector_load_and_store_out_of_bounds(%memref : memref<7xf32>) { 506 %c0 = constant 0 : index 507 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<7xf32>, vector<8xf32> 508 %0 = vector.load %memref[%c0] : memref<7xf32>, vector<8xf32> 509 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<7xf32>, vector<8xf32> 510 vector.store %0, %memref[%c0] : memref<7xf32>, vector<8xf32> 511 return 512} 513 514// CHECK-LABEL: @vector_load_and_store_2d_scalar_memref 515func @vector_load_and_store_2d_scalar_memref(%memref : memref<200x100xf32>, 516 %i : index, %j : index) { 517 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<4x8xf32> 518 %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<4x8xf32> 519 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xf32>, vector<4x8xf32> 520 vector.store %0, %memref[%i, %j] : memref<200x100xf32>, vector<4x8xf32> 521 return 522} 523 524// CHECK-LABEL: @vector_load_and_store_2d_vector_memref 525func @vector_load_and_store_2d_vector_memref(%memref : memref<200x100xvector<4x8xf32>>, 526 %i : index, %j : index) { 527 // CHECK: %[[ld:.*]] = vector.load %{{.*}}[%{{.*}}] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 528 %0 = vector.load %memref[%i, %j] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 529 // CHECK: vector.store %[[ld]], %{{.*}}[%{{.*}}] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 530 vector.store %0, %memref[%i, %j] : memref<200x100xvector<4x8xf32>>, vector<4x8xf32> 531 return 532} 533 534// CHECK-LABEL: @masked_load_and_store 535func @masked_load_and_store(%base: memref<?xf32>, %mask: vector<16xi1>, %passthru: vector<16xf32>) { 536 %c0 = constant 0 : index 537 // CHECK: %[[X:.*]] = vector.maskedload %{{.*}}[%{{.*}}], %{{.*}}, %{{.*}} : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 538 %0 = vector.maskedload %base[%c0], %mask, %passthru : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 539 // CHECK: vector.maskedstore %{{.*}}[%{{.*}}], %{{.*}}, %[[X]] : memref<?xf32>, vector<16xi1>, vector<16xf32> 540 vector.maskedstore %base[%c0], %mask, %0 : memref<?xf32>, vector<16xi1>, vector<16xf32> 541 return 542} 543 544// CHECK-LABEL: @gather_and_scatter 545func @gather_and_scatter(%base: memref<?xf32>, %indices: vector<16xi32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) { 546 // CHECK: %[[X:.*]] = vector.gather %{{.*}}[%{{.*}}], %{{.*}}, %{{.*}} : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 547 %0 = vector.gather %base[%indices], %mask, %pass_thru : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 548 // CHECK: vector.scatter %{{.*}}[%{{.*}}], %{{.*}}, %[[X]] : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> 549 vector.scatter %base[%indices], %mask, %0 : memref<?xf32>, vector<16xi32>, vector<16xi1>, vector<16xf32> 550 return 551} 552 553// CHECK-LABEL: @expand_and_compress 554func @expand_and_compress(%base: memref<?xf32>, %mask: vector<16xi1>, %pass_thru: vector<16xf32>) { 555 %c0 = constant 0 : index 556 // CHECK: %[[X:.*]] = vector.expandload %{{.*}}[{{.*}}], %{{.*}}, %{{.*}} : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 557 %0 = vector.expandload %base[%c0], %mask, %pass_thru : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 558 // CHECK: vector.compressstore %{{.*}}[{{.*}}], %{{.*}}, %[[X]] : memref<?xf32>, vector<16xi1>, vector<16xf32> 559 vector.compressstore %base[%c0], %mask, %0 : memref<?xf32>, vector<16xi1>, vector<16xf32> 560 return 561} 562 563// CHECK-LABEL: @extract_insert_map 564func @extract_insert_map(%v: vector<32xf32>, %v2: vector<16x32xf32>, 565 %id0 : index, %id1 : index) -> (vector<32xf32>, vector<16x32xf32>) { 566 // CHECK: %[[V:.*]] = vector.extract_map %{{.*}}[%{{.*}}] : vector<32xf32> to vector<2xf32> 567 %vd = vector.extract_map %v[%id0] : vector<32xf32> to vector<2xf32> 568 // CHECK: %[[V1:.*]] = vector.extract_map %{{.*}}[%{{.*}}, %{{.*}}] : vector<16x32xf32> to vector<4x2xf32> 569 %vd2 = vector.extract_map %v2[%id0, %id1] : vector<16x32xf32> to vector<4x2xf32> 570 // CHECK: %[[R:.*]] = vector.insert_map %[[V]], %{{.*}}[%{{.*}}] : vector<2xf32> into vector<32xf32> 571 %r = vector.insert_map %vd, %v[%id0] : vector<2xf32> into vector<32xf32> 572 // CHECK: %[[R1:.*]] = vector.insert_map %[[V1]], %{{.*}}[%{{.*}}, %{{.*}}] : vector<4x2xf32> into vector<16x32xf32> 573 %r2 = vector.insert_map %vd2, %v2[%id0, %id1] : vector<4x2xf32> into vector<16x32xf32> 574 // CHECK: return %[[R]], %[[R1]] : vector<32xf32>, vector<16x32xf32> 575 return %r, %r2 : vector<32xf32>, vector<16x32xf32> 576} 577 578