xref: /llvm-project/mlir/test/Dialect/Vector/ops.mlir (revision 35df525fd00c2037ef144189ee818b7d612241ff)
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